BIO(blocking io)
传统的网络io模式,面向流,一个线程对接一个会话,因此高并发时会因线程阻塞而性能低效
Java代码:
public class BIO implements Connector {
private Integer port = 8080;
@Override
public void start() throws IOException {
ServerSocket serverSocket = new ServerSocket(port);
LogUtil.getLogger().debug("端口"+port+"启动");
while (true){
final Socket socket = serverSocket.accept();
ThreadUtil.threadPool.execute(new Runnable() {
@Override
public void run() {
handler(socket);
}
});
}
}
public static void handler(Socket socket){
try {
byte[] bytes = new byte[1024];
InputStream inputStream = socket.getInputStream();
while (true){
int status = inputStream.read(bytes);
if(status!=-1){
LogUtil.getLogger().debug(new String(bytes,0,status));
}else {
break;
}
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if(Objects.nonNull(socket)){
try {
socket.close();
LogUtil.getLogger().debug("关闭链接");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
代码逻辑:
1、实现客户端tcp连接:Socket socket = serverSocket.accept(port)
2、调用额外线程实现socket监听和读写:如socket.read();
【注:】
accept方法的原理
1、(调用os的接口)告诉操作系统,当前程序的socket指定了8888端口,当端口收到连接信息之后,会把消息通过DMA的方式放到一个缓存区中,并唤醒注册在os中的阻塞线程,让这个线程到缓存区处理连接消息。(或者缓存区由socket程序指定)
2、端口有连接进来时,给cpu发中断,然后由该方法所在线程处理连接
作者:旧时光1234
链接:https://www.jianshu.com/p/f49d8792254d
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
NIO(non-blocking io)
bio的性能瓶颈促生了nio,nio面向缓存,可以实现单个线程对接多个会话,例如当前会话出现阻塞则遍历下个会话
JDK1.4起JDK源码提供nio包,主要由三大核心构成:selector、channel、buffer(基于linux系统select函数)
selector、channel、buffer之间的关系
selector对应一个线程,selector管理多个channel,channel相当于一个连接,channel对应一个buffer用于缓存会话
【注】:
channel是双向的,也就是支持读写,这点有别于bio,比如bio读用input,写用output
buffer
常用的buffer实现:ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、DoubleBuffer、FloatBuffer...参考文献:011_尚硅谷_Buffer的机制及子类_哔哩哔哩_bilibili011_尚硅谷_Buffer的机制及子类是尚硅谷Netty视频教程(B站超火,好评如潮)的第11集视频,该合集共计116集,视频收藏或关注UP主,及时了解更多相关视频内容。https://www.bilibili.com/video/BV1DJ411m7NR?p=11&vd_source=8be621c052fd9f705308579363b67881
selector
1、当serverSocketChannel连接上客户端后生成socketChannel;
2、当socketChannel注册到selecor上时会注册一个selectorKey,register(Selector sel, int ops)#SelectorKey