Java DatagramChannel.close()在Windows上保持端口打开
我正在实施一个发现过程,该过程:Java DatagramChannel.close()在Windows上保持端口打开,java,udp,nio,Java,Udp,Nio,我正在实施一个发现过程,该过程: 打开UDP套接字以侦听给定端口上的广播响应 发送一些请求(并期待稍后的响应) 在给定的时间段后关闭UDP套接字 第一个电话有效。但另一个调用得到绑定错误。已在使用的地址:bind 我正在运行Windows7。我做了一些测试,发现在一个通道之后;Netstat仍然提供: netstat-a-b-sp udp | grep 55224 UDP 0.0.0.0:55224: 因此,udp端口仍然在操作系统级别打开 我搜索了web,可能是操作系统级别的漏洞: 我运行
- 打开UDP套接字以侦听给定端口上的广播响应
- 发送一些请求(并期待稍后的响应)
- 在给定的时间段后关闭UDP套接字
public void testConnectCloseWithSocket(){
长t累积=0;
内部勘误表=-1;
System.out.println(“开始…”);
对于(int i=0;i<4000;i++){
试一试{
勘误表=i;
DatagramSocket结果=新DatagramSocket(空);
bind(新的InetSocketAddress(InetAddress.getLocalHost(),9005));
result.close();
//终于成功了
t累积=0;
}捕获(例外e){
System.out.println(“错误(at=“+errAt+”)(waited=“+tCumulative+”ms):“+e.getMessage());
t累计+=50;
试一试{
睡眠(50);
}捕捉(中断异常e1){
}
我--;
}
}
System.out.println(“结束…”);
}
结果套接字 我确实收到了一些错误,但套接字已正确关闭。。。那是 oki满足我的需要 不,如果您有错误,您的频道未正确关闭 您必须在
try
块的finally
子句中执行close
Selector selector = Selector.open();
try
{
DatagramChannel channel = DatagramChannel.open();
try
{
channel.configureBlocking(true);
channel.socket().bind(
new InetSocketAddress(InetAddress.getLocalHost(), 9005)
);
SelectionKey clientKey = channel.register(selector, SelectionKey.OP_READ);
clientKey.cancel();
}
finally
{
channel.close();
}
}
finally
{
selector.close( )
}
如果使用选择器注册通道,则通道关闭的某些部分将推迟到下一个select()。它被记录在Selector、AbstractSelector、SelectorSpi、SelectableChannel、AbstractSelectableChannel的森林中的某个地方,在我需要它的时候我永远找不到它。如果在关闭频道时处于select循环和线程中,可以通过调用selectNow()立即执行该循环。感谢您的提示,在处理代码时,我注意到我没有关闭选择器。通过关闭它,一切正常:-)谢谢@这是因为我在回答中提出的问题。
public void testConnectCloseWithChannel() {
long tCumulative = 0;
int errAt = -1;
System.out.println("start...");
for (int i = 0; i < 4000; i++) {
try {
errAt = i;
Selector selector = Selector.open();
DatagramChannel channel = DatagramChannel.open();
channel.configureBlocking(true);
channel.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
SelectionKey clientKey = channel.register(selector, SelectionKey.OP_READ);
clientKey.cancel();
channel.close();
//success at last
tCumulative = 0;
} catch (Exception e) {
System.out.println("Error (at="+errAt+") (waited="+tCumulative+"ms): " + e.getMessage());
tCumulative+=50;
try {
Thread.sleep(tCumulative);
} catch (InterruptedException e1) {
}
i--;
}
}
System.out.println("end...");
}
Selector selector = Selector.open();
try
{
DatagramChannel channel = DatagramChannel.open();
try
{
channel.configureBlocking(true);
channel.socket().bind(
new InetSocketAddress(InetAddress.getLocalHost(), 9005)
);
SelectionKey clientKey = channel.register(selector, SelectionKey.OP_READ);
clientKey.cancel();
}
finally
{
channel.close();
}
}
finally
{
selector.close( )
}