首页 > 解决方案 > java.net.BindException:无法在 LinkLocal 重新绑定上分配请求的地址(绑定失败)

问题描述

我正在使用 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 地址

标签: javanetwork-programmingudpipv6link-local

解决方案


推荐阅读