我正在实施一个发现流程:
- 打开 UDP 套接字以侦听给定端口上的广播响应
- 发送一些请求(并期待稍后的响应)
- 在给定时间段后关闭 UDP 套接字
第一次通话有效。但其他调用会出现绑定错误。地址已被使用:绑定
我运行的是Windows 7。我做了一些测试,发现在channel.close();之后Netstat 仍然给出:
netstat -a -b -sp udp | netstat -a -b -sp udp | grep 55224
UDP 0.0.0.0:55224:
所以udp端口还是在OS层面开放的
我在网上搜索了一下,可能是操作系统级别的泄漏:一些java数据报套接字问题 https://stackoverflow.com/questions/6361741/some-java-datagram-socket-questions
我运行了 2 个测试,一个使用 NIO 通道,另一个不使用(来自在网上找到的测试)。我用 NIO 版本重现了我的错误,但如果我不使用 NIO,它就会工作。
任何人都可以告诉我如何让它与 NIO 一起工作。目标平台是Android,我不知道t wan
始终收听广播,但仅限于重复的一段时间。
测试插座
public void testConnectCloseWithSocket() {
long tCumulative = 0;
int errAt = -1;
System.out.println("start...");
for (int i = 0; i < 4000; i++) {
try {
errAt = i;
DatagramSocket result = new DatagramSocket(null);
result.bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
result.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(50);
} catch (InterruptedException e1) {
}
i--;
}
}
System.out.println("end...");
}
结果套接字
开始...
错误(at=1319)(等待=0ms):地址已在使用中:无法绑定
错误(at=1438)(等待=0ms):地址已在使用中:无法绑定
错误(at=1587)(等待=0ms):地址已在使用中:无法绑定
错误(at=1740)(等待=0ms):地址已在使用中:无法绑定
end...
我确实遇到了一些错误,但套接字正确关闭...这适合我的需要
使用通道进行测试
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...");
}
注意:如果对channel.register进行注释,则测试有效..
渠道结果
开始...
错误(at=0)(等待=0ms):null
错误(at=0)(等待=50ms):地址已在使用中:绑定
错误(at=0)(等待=100ms):地址已在使用中:绑定
错误(at=0)(等待=150ms):地址已在使用中:绑定
...
谢谢你的帮助