NIO 编程记录
Selector的使用
首先要创建一个Selector,并把channel注册到selector上
readSelector = Selector.open(); key = channel.register(selector, registerOps);
使用线程不断对select()进行轮询。
这是一个阻塞的方法,只有在一个以上channel处于ready时,才会返回就绪channel的数量,并把就绪channel的selectionkey放入Set中
对就绪的Selectionkey遍历,并且结束后要对Set进行clear才能进行下一次select()
Set<SelectionKey> selectionKeys = readSelector.selectedKeys(); for (SelectionKey selectionKey : selectionKeys) { if (selectionKey.isValid()) { handleSelection(selectionKey, SelectionKey.OP_READ, inputCallbackMap, inputHandlePool); } } selectionKeys.clear();
在处理数据之前,先要取消响应的监听,因为消息的读取是一个异步的线程,在它还未完成从channel中读取数据之前,selector会一直收到该channel就绪的信息。在完成读取之后,再进行监听的重新注册。
// 重点 // 取消继续对keyOps的监听 key.interestOps(key.readyOps() & ~keyOps);
传输信息容易出现的问题
- 重复接收
- 消息粘包
- 消息不完整