什么是NIO模型呢?
之前版本
Java网络编程-Socket编程(三伪异步I/O模型的简版多人聊天室)
服务器
这里使用Channel、Selector、Buffer来实现一个NIO模型的服务器,服务器的主要逻辑如下:
首先创建ServerSocketChannel(服务器管道),拿到关于该ServerSocketChannel的ServerSocket,并且将ServerSocket绑定端口(源码中也间接实现了监听端口,之前的版本有说过,这里就不再赘述了),再创建Selector,将创建的ServerSocketChannel的ACCEPT事件注册到Selector上(也就是当有客户端连接服务器时触发事件)。
当有客户端连接后(即Selector监听到ServerSocketChannel的ACCEPT事件触发了),就获取该客户端的SocketChannel,并将SocketChannel的READ事件注册到Selector上(当有客户端发送消息给服务器时触发)。
当有客户端发送消息给服务器时,服务器将该消息转发给其他用户,因为在线用户的SocketChannel都在Selector上注册了READ事件,所以服务器可以很方便的拿到用户的SocketChannel(所有在线用户的管道),所以服务器转发消息就变得十分简单了;最后还要判断用户输入的消息是否是要准备退出,如果用户要退出,就移除该用户SocketChannel的READ事件,并且提醒Selector。
像BIO模型和伪异步I/O模型实现的服务器,当有客户端连接服务器后,服务器需要创建一个线程来与用户进行通信,当客户端连接请求并发数很大时,服务器需要创建的线程就非常多了,这样带来的上下文切换、内存开销都非常大,并且创建的线程还是阻塞式的,性能较差。而NIO模型,客户端与服务器通信是通过Channel、Buffer(BIO模型和伪异步I/O模型是使用Stream),并且当客户端连接服务器时,NIO模型不需要创建线程,只需要将用户管道的READ事件注册到Selector即可,用户发送消息给服务器就会触发该事件,而不需要创建线程去一直阻塞式的监听用户发送过来消息,有了Selector,实现非阻塞通信就变得很简单了。
代码中注释还是比较详细的,相信大家都能看懂。如果对ByteBuffer的读、写模式不太懂,可以看下面这篇博客的相关部分。