我正在使用 UDP 在 Java 中编写一个网络框架原型,以处理使用它的设备可能没有永久和/或可靠连接的时刻以及它应该如何处理它。我必须能够将它与“普通”IPv4 和 IPv6 地址以及 IPv6 LinkLocal 地址一起使用。
由于这个概念,有时设备会失去连接,我必须关闭绑定到特定 IP/端口对的所有 DatagramSocket,这样我才能释放资源,一旦设备获得新连接,我需要“重新绑定”套接字以给定的地址。
当我使用“普通”IPv4 和 IPv6 地址进行测试时,代码没有问题,但是一旦我开始使用 IPv6 LinkLocal 地址,当我尝试将 DatagramSocket 重新绑定到任何 LinkLocal 地址时,就会出现此异常:
java.net.BindException: Cannot assign requested address (Bind failed)
at java.base/java.net.PlainDatagramSocketImpl.bind0(Native Method)
at java.base/java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:131)
at java.base/java.net.DatagramSocket.bind(DatagramSocket.java:394)
由于此代码适用于非 LinkLocal 地址,我认为它也适用于 LinkLocal 地址。
这是我用来将 DatagramSocket 绑定到 IP/端口对的代码:
private void bindDatagramSocket() {
try {
this.ds = new DatagramSocket(null);
InetSocketAddress isa = new InetSocketAddress(this.ip, this.port);
this.ds.bind(isa);
this.hasConnection = true;
}
catch (SocketException e) {
e.printStackTrace();
}
this.ip 和 this.port 由另一个线程更新,该线程检测到可用地址和连接状态(有/无连接)的变化。当检测到连接丢失时,我使用此代码关闭正在使用的 DatagramSocket (this.ds)
public void updateConnectionStatus(boolean value){
this.connectionLock.lock();
this.hasConnection = value;
this.connectionLock.unlock();
if(value && !this.isRunning){
new Thread(this).start();
}
else{
if(!value) {
this.ds.close();
this.ds = null;
}
}
任何建议表示赞赏
TL;DR:使用 DatagramSockets 绑定到对应于 IPv6 LinkLocal 地址的 IP/端口对,关闭该 DatagramSocket 并将其重新绑定到相同的 IPv6 LinkLocal 地址会导致异常,即使相同的代码适用于我可以测试的任何其他情况“正常” IPv4 和 IPv6 地址