了解一下NIO
来源:互联网 发布:拳皇98出招优化 编辑:程序博客网 时间:2024/04/29 09:31
NIO(Non-block I/O)初学
- 解释:非阻塞I/O
类库
- 缓冲区(buffer)
- I/O操作,将数据写入缓冲区,方便特有操作,也方便网络读写。
- 通道(channel)
- 通道是双向的,可以同时进行读写,网络数据通过Channel读取和写入;stream(流)是单向的,只能读或者写
- 通道分为两大类:用于网络读写的SelectableChannel和文件操作的FileChannel
- ServerSocketChannel和SocketChannel都是SelectableChannel子类
- 多路复用器(Selector):轮询出发生读或写操作的Channel
- JDK使用epoll(),只需要一个线程负责Selector轮询。
Java原生NIO编程
NIO服务端序列图
- 打开ServerSocketChannel,用于监听客户端的连接,它是所有客户端连接的父管道。ServerSocketChannel acceptorSvr = ServerSocketChannel.open();
- 绑定监听端口,设置连接方式为非阻塞模式
( acceptorSvr .socket().bind(new InetSocketAddress(InetAddress.getByName(“IP”),port));
acceptorSvr .configureBlocking(false)) - 创建Reactor线程,创建多路复用器并启动线程(
Selector selector =Selector.open();
New Thread(new ReactorTask()).start();
) - 将ServerSocketChannel注册到Reactor线程的多路复用器Selector上,监听ACCEPT事件
SelectionKey key = acceptorSvr.register(selector,SelectionKey.OP_ACCEPT,ioHandler); - 多路复用器在线程run方法的无限循环轮询准备就绪的Key
int num = selector.select();
Set selectedKeys = selector.selectedKeys();
Iterator it = selectedKeys.iterator();
while(it.hasNext()){
SelectionKey key = (SelectionKey)it.next();
//… deal with I/O event
} - 多路复用器监听到有新的客户端接入,处理新的接入请求,完成tcp三次握手,建立物理链路。
SocketChannel channel =svrChannel.accept(); - 设置客户端链路为非阻塞模式
channel.configureBlocking(false);
channel.socket().setReuseAddress(true); - 将新接入的客户端连接注册到Reactor线程的多路复用器上,监听读操作,读取客户端发送的网络信息
SelectionKey key = socketChannel.register(selector,SelectionKey.OP_READ,ioHandler); - 异步读取客户端请求消息到缓冲区
int readNumber = channel.read(receivedBuffer); 对ByteBuffer进行编解码,如果有半包消息指针reset,继续读取后续的报文,将解码成功的消息封装成Task,投递到业务线程池中,进行业务逻辑编排。
Object message =null;
while(buffer.hasRemain()){
byteVuffer.mark();
Object message = decode(byteBuffer)’
if(message == null){
byteBuffer.reset();
break;
}
messageList.add(message);
}
if(!byteBuffer.hasRemain()){
byteBuffer.clear()
}else{
byteBuffer.compact();
}
if(messageList!=null& !messageList.isEmpty()){
for(Object messageE :messageList){
handlerTask(messageE);
}
}将pojo对象encode(编码)成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端。
socketChannel.write(buffer);
- 缓冲区(buffer)
Netty NIO
- 运行环境
IDE(Eclipse、intelIED…)、Netty.jar - 服务器端
a.开发步骤
1、配置服务端的NIO线程组
2、绑定端口,同步等待成功
3、等待服务端监听端口关闭
4、退出,释放线程组资源 - 客户端
1、配置客户端的NIO线程组
2、 创建客户端辅助启动类Bootstrap,进行配置
3、设置ChannelHander到管道(ChannelPipleline)中,用于处理IO事件
4、辅助类设置完成调用connect发起异步连接,然后调用同步方法等待连接成功。
5、客户端连接关闭,客户端主函数退出,释放资源
打包部署
1、eclipse导出jar包
2、ant打包工具
3、Maven工程构建
TCP粘包/拆包问题的解决之道
TCP粘包/拆包解决策略
1、消息定长2、在包尾增加回车换行符进行分割3、将消息分为消息头和消息体4、更复杂的应用层协议
LineBasedFrameDecoder和StringDecoder原理
LingBasedFrameDecoder的工作原理:
依次遍历ByteBuf中可读的字节,判断是否存在“\n”或者"\r\n"作为结束位置的标志。 1、以换行符作为结束标志的解码器 2、支持携带结束符或者不携带结束符两种解码方式 3、支持配置单行的最大长度
Stringdecoder功能简单:
1、将接收到的对象转换成字符串2、调用后面的handler
LingBasedFrameDecoder和StringDecoder组合就是按行切换的文本解码器,用来支持TCP的粘包和拆包。
分隔符和定长解码器的应用
另外两种解码器(都能解决TCP粘包和拆包导致的读半包问题): 1、DelimiterBasedFrameDecoder:自动完成以分隔符作为结束标志的消息解码 2、FixedLengthFrameDecoder:自动完成对定长消息的解码
DelimiterBasedFrameDecoder 应用
- 小小了解一下NIO
- 了解一下NIO
- Java NIO 简单了解
- Java nio初步了解
- Java NIO 简单了解
- Java NIO 简单了解
- Java NIO初步了解
- Java NIO 简单了解
- 了解一下JSON
- 了解一下版权贸易
- 了解一下“PV”
- 了解一下语义网
- 了解一下NTLM
- 了解一下NginX
- 了解一下Resin
- 了解一下cics
- 了解了一下cache
- 了解一下HDMI标准
- 智能制造核心技术在哪里?
- 17、spring AOP通知——Pointcut、Advisor
- 多线程用到的概念知识点
- Android WIFI IP
- php网站配置apache
- 了解一下NIO
- ZCMU—1881
- TensorFlow学习笔记之源码分析(1)----最近算法nearest_neighbor
- sqlserver复制表命令
- fatal error LNK1181: 无法打开输入文件“hid.lib setupapi.lib
- 对session和cookie的理解
- MySQL数据库——初涉‘连接’基本语法
- 四旋翼飞行器Quadrotor飞控之 PID调节(参考APM程序)
- #ifdef _DEBUG