最近在研究非阻塞通信socket编程,有个问题不明白~
如果某个SocketChannel对象sc,像某个Selector对象selector注册了READ和WRITE事件,然后调用selector.select()监听事件,书上说当写就绪(writeable)或者读就绪(readable)的时候,select()方法才返回,然后进行判断,再进行发送或者读取,可是系统是怎么知道已经进入写就绪状态或者读就绪状态呢?实际中也没有像单击按钮这样的动作来触发事件啊~~一直想不明白~~~~请赐教~~~~另外,对于高并发量的应用,是用非阻塞,还是用线程池,那个更有效率?
如果某个SocketChannel对象sc,像某个Selector对象selector注册了READ和WRITE事件,然后调用selector.select()监听事件,书上说当写就绪(writeable)或者读就绪(readable)的时候,select()方法才返回,然后进行判断,再进行发送或者读取,可是系统是怎么知道已经进入写就绪状态或者读就绪状态呢?实际中也没有像单击按钮这样的动作来触发事件啊~~一直想不明白~~~~请赐教~~~~另外,对于高并发量的应用,是用非阻塞,还是用线程池,那个更有效率?
非阻塞很多情况下能够支持非常庞大的客户接入,不过编码上比较复杂,你可以尝试下mina!
高并发的请求,如果每个请求生命周期都很短,就用传统的方式,如果生命周期很长,比如作聊天程序
每个客户端都占一个长连接的,就可以考虑用nio
while(buffer.hasRemaining()) {
socketChannel.write(buffer);
}一次性全部写完,写完后取消写事件。
5~8 字节 int 功能
9~12 字节 int 请求内容长度
13~ 字节 byte 请求内容前 12 个字节类似于请求头,从第 13 个字节开如是请求正文,长度在请求头中可以获得。这样的话,我们只要从 13 个字节开始读满请求头中的长度字节这个报文就算全部读完了。
服务器S用ByteBuffer保存报文,假设足够大,两个客户端A、B都会发送长度为10的报文给服务器,按照Buffer会分几批读完的规律,会不会出现在这几次读取中每次读取的位置不一样,比如第一次读取A的2个报文,第二次读取B的2个报文,最后读完的buffer里内容是A、B的混合报文~~
还是说每次通过SelectionKey的channel()方法返回的SocketChannel只针对一个客户端~