### 介绍
![](https://img.kancloud.cn/37/14/3714356aa8b6fe52b25d0da61f8d9108_670x239.png)
### 同步IO之BlockingIO
![](https://box.kancloud.cn/56ff8ce655e799951d2d88150283f200_552x331.png)
如上图所示,用户进程process在Blocking IO读recvfrom操作的两个阶段都是等待的。在数据没准备好的时候,process原地等待kernel准备数据。kernel准备好数据后,process继续等待kernel将数据copy到自己的buffer。在kernel完成数据的copy后process才会从recvfrom系统调用中返回
### 同步阻塞式I/O
```
public class SocketServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8999);
while (true) {
Socket socket = server.accept();
new Thread(new ChannelSocker(socket)).start();
}
}
static class ChannelSocker implements Runnable {
private Socket socket;
public ChannelSocker(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
StringBuffer res = new StringBuffer();
try (InputStream inputStream = socket.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader read = new BufferedReader(reader);) {
String line = read.readLine();
while (line != null) {
res.append(line);
line = read.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
System.err.println("接收到消息" + res.toString());
}
}
}
}
```
阻塞型I/O,主要阻塞在两个地方:
1. 在调用InutStream.read方法是阻塞的,它会一直等到数据到来时(或超时)才会返回;
2. 在调用ServerSocket.accept方法时,也会一直阻塞到有客户端连接才会返回;
### setSoTimeout
serverSocket.setSoTimeout\(3000\); \#\# soTimeout将accept阻塞3秒
Socket socket = serverSocket.accept\(\);
```
try (ServerSocket serverSocket = new ServerSocket(8089)){
serverSocket.setSoTimeout(3000);
Socket socket = serverSocket.accept();
System.err.println("finished");
} catch (Exception e) {
e.printStackTrace();
}
System.err.println("end==>");
```
### SO\_RCVBUF
SO\_RCVBUF选项设置了服务器Socket接受的客户端Socket默认缓冲区大小
```
try (ServerSocket serverSocket = new ServerSocket(8089)){
serverSocket.setSoTimeout(3000);
serverSocket.setReceiveBufferSize(1024);
Socket socket = serverSocket.accept();
System.err.println("finished");
} catch (Exception e) {
e.printStackTrace();
}
System.err.println("end==>");
```
### 阻塞模型
![](https://img.kancloud.cn/ca/11/ca115d9a44177fe9bf1559e1415ef735_700x295.png)
### 阻塞型的I/O存在的问题
InputStream.read\(\)方法在其缓存区未满时会造成阻塞,只有数据填满了缓存区或者客户端关闭了套接字,方法才会返回;
BufferedReader创建了缓存区来从套接字中读入数据,但是同样创建了一些字符串存储这些数据,这些String很快变成垃圾需要回收;
InputStream 中的read方法用于读取数据,方法有3个重载:
* read\(\):从输入流读取下一个数据字节;
* read\(byte\[\] b\):从输入流中读取一定数量的字节并将其存储在缓冲区数组b中;
* read\(byte\[\] b, int off, int len\):将输入流中最多 len 个数据字节读入字节数组;
- 概述
- Netty&Tomcat的区别
- NIO基础知识
- 同步阻塞式IO
- 伪异步IO编程
- 同步IO之IO-multiplexing
- NIO基础概念
- NIO服务流程
- Netty基础知识
- NettyServer开发示例
- 零拷贝
- TCP粘包和拆包问题
- LineBasedFrameDecoder&StringDecoder
- 应用层消息处理方式
- ByteBuf
- ChannelHandler
- Netty核心组件
- Channel接口
- ChannelHandler
- ChannelInboundHandlerAdapter
- SimpleChannelInboundHandler
- SimpleChannelInboundHandler && ChannelInboundHandler
- ChannelInitializer
- EventLoop接口
- ChannelFuture接口
- ChannelPipeline接口
- 序列化
- JAVA序列化