第一次接触netty,此处作为学习笔记如有不正确地方,谢谢支出与建议。
原理网上很多,这里就不做过多诉述。
首先举个例子:
IO:每个小朋友配一个老师。每个老师隔段时间询问小朋友是否要上厕所,如果要上,就领他去厕所,100个小朋友就需要100个老师来询问,并且每个小朋友上厕所的时候都需要一个老师领着他去上,这就是IO模型,一个连接对应一个线程。
NIO:所有的小朋友都配同一个老师。这个老师隔段时间询问所有的小朋友是否有人要上厕所,然后每一时刻把所有要上厕所的小朋友批量领到厕所,这就是NIO模型,所有小朋友都注册到同一个老师,对应的就是所有的连接都注册到一个线程,然后批量轮询。
一、传送IO特点
1.服务端阻塞点server.accept();获取套接字的时候
inputStream.read(bytes);输入流读取数据的时候
2.传统socket是短连接,可以做短连接服务器,他无法做长连接,属于一问一答的模式,比如老的tomcat底层用的就是socket,用完就会关掉线程,因此不会出现线程一直被占用的情况,支持处理多个客户端连接
(1)单线程情况下只能有一个客户端(一个线程维护一个连接,也就是一个socket客户连接)线程一直被占用。
(2)用线程池可以有多个客户端连接,但是非常消耗性能(用此案城池,就是老tomcat原理,只不过是用完后就释放)
=======================分割线==========================二、NIO的特点
主要API介绍:
ServerSocketChannel对应传统IO中的ServerSocket。
SocketChannel对应传统IO中的Socket。
Selector 是NIO核心 ,负载监听 ServerSocketChannel与SocketChannel ,支持单线程连多个客户端;类似通道管理器而且底层是c实现的;线程拥有一个selector就可以支持多个客户端。
SelectionKey 相当于map中的key 相当于记录根据不同动作做不同事情,一个key一个事件。
三、NIO的一些疑问
1、客户端关闭的时候会抛出异常,死循环
解决方案
int read = channel.read(buffer);
if(read > 0){
byte[] data = buffer.array();
String msg = new String(data).trim();
System.out.println("服务端收到信息:" + msg);
//回写数据
ByteBuffer outBuffer = ByteBuffer.wrap("好的".getBytes());
channel.write(outBuffer);// 将消息回送给客户端
}else{
System.out.println("客户端关闭");
key.cancel();
}
2、 selector.select();阻塞:当注册事件到达时,方法返回,否则一直堵塞 。那为什么说nio是非阻塞的IO?
(1)、判断IO否阻塞的关注点是读取数据(read)的时候是否立马返回,NIO不管有无数据都会立马返回.而不是关注在 selector.select()或者是accept();
(2)、除此之外
selector.select()也是可以是非阻塞,也该有该方法,非阻塞方法如下:
selector.select(1000);是不阻塞方法
selector.wakeup();也可以唤醒selector 也是支持非阻塞的
selector.selectNow();也是支持非阻塞的
3、SelectionKey.OP_WRITE是代表什么意思
OP_WRITE表示底层缓冲区是否有空间,是则响应返还true,一般缓存区都是空闲的,一般不用注册该事件
四、原理流程图对比
IO:
NIO:
详细:请看该博文:https://blog.csdn.net/gududedabai/article/details/80783994是一个非常好的公众号,引进来的。