SocketChannel和ServerSocketChannel,两者的父类是SelectableChannel,它在jdk中的文档有这么段话:
Once registered with a selector, a channel remains
registered until it is deregistered.This involves deallocating whatever
resources were allocated to the channel by the selector.
A channel cannot be deregistered directly; instead, the key
representing its registration must be cancelled. Cancelling a key
requests that the channel be deregistered during the selector's next selection
operation.
也就是说关闭一个已经注册的SelectableChannel需要两个步骤:
1)取消注册的key,这个可以通过SelectionKey.cancel方法,也可以通过SelectableChannel.close方法,或者中断阻塞在该channel上的IO操作的线程来做到。
2)后续的Selector.selectXXX方法的调用才真正地关闭
本地Socket。
因而,如果,如果在取消SelectionKey后没有调用到selector的select方法(因为Client一般在取消key后,
我们都会终止调用select的循环,当然,server关闭一个注册的channel我们是不会终止select循环的),那么本地socket将进入CLOSE-WAIT
状态(等待本地Socket关闭)。简单的解决办法是在
SelectableChannel.close方法之后调用Selector.selectNow方法,类似:
Selector sel;
SocketChannel sch;
// …
sch.close();
sel.selectNow();
Nio编程有很多这样细节性的东西需要注意,通常情况下还是利用成熟的框架为妙。
分享到:
相关推荐
常连接是指一个持久存在的TCP连接,避免了频繁创建和销毁连接带来的系统资源消耗和性能损耗。然而,当应用需要与多个后台服务交互时,传统的串行处理模式(即逐一访问每个服务)会导致性能瓶颈和系统健壮性下降。 ...
5. `Pipe`:提供了一个单向的数据通道,用于在Java线程之间传递数据。 Java NIO的使用步骤通常包括: 1. 创建选择器并注册感兴趣的通道。 2. 配置通道为非阻塞模式。 3. 在循环中调用选择器的`select()`方法,获取...
- 每个Channel与一个ChannelHandlerContext相对应,而每个ChannelHandlerContext又与一个特定的Channel相关联。 #### ChannelPipeline - `ChannelPipeline`是一个包含多个`ChannelHandler`的链表,用于处理入站和...
QQ作为一个即时通讯软件,其背后的原理也离不开Socket通信。在这个项目中,我们将学习如何利用Java的Socket API来模拟实现一个简单的QQ聊天功能。 首先,理解Socket的概念至关重要。Socket在计算机网络中可以被视为...
JavaSelector在Java NIO(非阻塞I/O)中扮演着关键角色,它允许程序同时监控多个通道(channels)的事件,例如连接请求、数据可用性或者关闭事件,而无需在一个单独的线程中轮询所有通道。这种机制极大地提高了处理...
最后,Java 7的`try-with-resources`语句与NIO.2结合,使得资源关闭更加安全可靠,避免了传统的finally块可能导致的资源泄露问题。 总结来说,Java 7的NIO.2 API带来了以下关键改进: 1. 更强大的文件系统操作,如`...