网络I/O:
1,BIO(同步阻塞)
2,伪异步IO(同步阻塞)
3,NIO(同步非阻塞)
4,AIO(异步非阻塞)
阻塞与非阻塞,同步与异步区别:
阻塞非阻塞:程序是否继续向下执行.
同步:一直等到有结果才返回.
异步:立即返回,有结果会得到通知.
所以,
同步阻塞:发出一个请求,一直等到有结果才返回,并继续执行.
同步非阻塞:发出一个请求,程序继续执行,隔一段时间会检查结果,有结果才返回.
异步阻塞:发出一个请求,不管有无结果立即返回,但程序不继续执行,等待结果通知,得到通知后继续执行.
异步非阻塞:发出一个请求,不管有无结果立即返回,程序继续执行,等待结果通知.
一,BIO
基于BIO的通信,服务端会阻塞,即服务端在监听端口时每accept一个客户端连接,就去处理请求,此时其他客户端连接只能阻塞等待。
服务端:新建一个serverSocket,循环监听port,没有请求阻塞在accept(),有请求便处理请求。
- Socket socket = null;
- try {
- ServerSocket serverSocket = new ServerSocket(this.port);
- while(true) {
- socket = serverSocket.accept(); // 监听
- this.handleMessage(socket); // 处理客户端请求,具体如何处理就不写了
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- Socket socket = null;
- OutputStream out = null;
- InputStream in = null;
- try {
- socket = new Socket(ipAddress, port); // 连接服务端
- // 发送请求
- out = socket.getOutputStream();
- out.write(data);
- out.flush();
- // 接收响应
- in = socket.getInputStream();
- int totalBytes = 0;
- int receiveBytes = 0;
- byte[] receiveBuffer = new byte[128];
- if((receiveBytes=in.read(receiveBuffer))!=-1) {
- totalBytes += receiveBytes;
- }
- String serverMessage = new String(receiveBuffer, 0, receiveBytes);
- System.out.println("Client: receives serverMessage->" + serverMessage);
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- // 发送请求并接收到响应,通信完成,关闭连接
- out.close();
- in.close();
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
伪异步在BIO的基础上,增加了线程池,实现1个线程可以管理n个连接。
三,NIO
buffer,channel,selector
服务端:
1,打开ServerSocketChannel
2,绑定监听地址和端口
3,创建Selector,启动线程
4,将ServerSocketChannel注册到Selector上,监听Accept事件
5,Selector轮询就绪队列
6,监听到有新客户端连接,
7,设置新客户端连接的Socket参数
8,新SocketChannel注册Selector上,监听读事件
9,监听到读事件,读取消息到缓冲区
10,将应答消息异步发送给客户端
客户端:
1,打开SocketChannel
2,设置SocketChannel为非阻塞的,以及TCP参数
3,创建Selector
4,创建SocketChannel,并注册Connect事件
5,Selector轮询就绪队列
6,连接成功,注册读事件,发送请求消息
7,监听到read事件,读取应答消息
四,AIO(NIO2.0)
服务端:
客户端: