基于IO、NIO、Netty的Client和Server之间的Java程序

一、IO实现

1.1 传统IO的特点

  • 代码执行时会存在两个阻塞点
server.accept();     等待链接
inputStream.read(bytes);     等待输入
  • 单线程情况下只能为一个客户端服务;
  • 用线程池可以有多个客户端连接,但是非常消耗性能;
  • 使用传统的I/O程序读取文件内容, 并写入到另一个文件(或Socket), 如下程序:
File.read(fileDesc, buf, len);
Socket.send(socket, buf, len);

会有较大的性能开销, 主要表现在一下两方面:

上下文切换(context switch), 此处有4次用户态和内核态的切换;
Buffer内存开销, 一个是应用程序buffer, 另一个是系统读取buffer以及socket buffer;

1.2 项目实现

1.创建两个Java项目
在这里插入图片描述
2.分别创建两个类,Server和Client
3.编写代码
Server服务端:

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
   
    public static void main(String[] args) throws IOException{
   
        //创建客户端的Socket对象(SevereSocket)
        //ServerSocket (int port)创建绑定到指定端口的服务器套接字
        ServerSocket serverSocket=new ServerSocket(6000);

        //Socket accept()侦听要连接到此套接字并接受它
        Socket socket=serverSocket.accept();

        //获取输入流,读数据,并把数据显示在控制台
        InputStream inputStream=socket.getInputStream();
        byte[] bytes=new byte[1024];
        int len=inputStream.read(bytes);
        String data=new String(bytes,0,len);
        System.out.println("数据是:"+data);
        //释放资源
        socket.close();
        serverSocket.close();
    }
}

Client客户端:

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
   
    public static void main(String[] args) throws IOException{
   
        //创建客户端的Socket对象
        //Socket (InetAddress adress,int port)创建流套接字并将其连接到指定IP地址的指定端口号
        //Socket (String host,int port)创建流套接字并将其连接到指定主机的指定端口号
        Socket s=new Socket("192.168.0.102", 6000);

        //获取输出流,写数据
        //OutputStream getOutputStream();返回此套接字的输出流
        OutputStream os=s.getOutputStream();
        os.write("你好,服务器端!".getBytes());

        //释放资源
        s.close();
    }
}

1.3 结果

在这里插入图片描述

二、NIO实现

2.1NIO特点

  • NIO在单线程下可以同时为多个客户端服务
  • NIO技术省去了将操作系统的read buffer拷贝到程序的buffer, 以及从程序buffer拷贝到socket buffer的步骤, 直接将 read buffer 拷贝到 socket buffer. java 的 FileChannel.transferTo() 方法就是这样的实现, 这个实现是依赖于操作系统底层的sendFile()实现的.
	public void transferTo(long position, long count, WritableByteChannel target);

它的底层调用的是系统调用sendFile()方法

	sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

2.2 IO与NIO的差别

在这里插入图片描述
具体参考:Netty入门(一)——传统IO与NIO比较(一)

2.3 项目实现

1.同样新建两个Java项目
2.分别建一个Server类和Client类

Server服务器端:

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值