【发布时间】:2011-04-25 16:18:29
【问题描述】:
我正在客户端的 Java 代码库上执行 Maven 构建,但其中一个测试套件失败了。日志中报告的错误与我使用 NetBeans 调试器单步调试代码时发现的错误相同。
本机函数java.net.PlainDatagramSocketImpl.send() 正在抛出BindException - “无法分配请求的地址”。我不能比这更深入地研究代码,因为它是一个原生函数。
在更高级别上,代码正在执行网络的基本测试。
DatagramSocket ds = new DatagramSocket(service.getNetworkConfiguration().getBindSocketAddress().getPort() + 100);
InetSocketAddress bindSocketAddress = service.getNetworkConfiguration().getBindSocketAddress();
ds.send(new DatagramPacket(message, message.length, bindSocketAddress.getAddress(), bindSocketAddress.getPort()));
service 返回的 IP 地址,因此包含在 bindSocketAddress 中,如上所述,我尝试了不同的端口(32168、22332、1234),但都出现相同的错误。
+ 100 出现在DatagramSocket 端口的定义中显然是有意为之的,而且这个测试套件已经为其他人成功了很长时间,并且已经到位。
我在 64 位的 Windows 7 上运行。
我已禁用本地计算机上的防火墙和防病毒软件,并且我运行了netstat -a,但在绑定端口列表中我没有看到任何我使用过的端口。
这可能是我的 Windows 配置甚至我的路由器的问题吗?也许我的Java配置以某种方式?任何建议将不胜感激。
跟进:我在 CentOS 5.5 虚拟机上运行时收到 IDENTICAL 错误。不过,它仍然可能是 Windows 7 配置问题,因为 VM 来宾正在 Windows 7 主机上运行 - 共享其 Internet 连接。 (桥接)
跟进#2(见第 4 条评论):让收件人成为0.0.0.0 似乎无效;实际上,JDK(InetAddress.java)中的一条注释说:未指定的地址(也称为anylocal或通配符地址)不得用作通配符地址所在的IP数据包的目标地址 0.0.0.0。我将代码更改为使用“localhost”(参见第 4 条评论),它解决了问题。但是,由于我不明白的原因,上面的代码可能是有效的;当我与代码的开发人员澄清时,我会发布跟进或答案。
更新(2012 年 3 月 1 日):事实证明(回想起来)事实上,有问题的代码只是以前程序员部分的错误。我真正的误解与问题的主题完全无关。
解释是:每次构建 Java 代码时,我都会运行系统内置的相关单元测试。那时我没有意识到可以构建源代码,但绕过单元测试。事实证明,团队中的另一位程序员已经构建了代码(成功),但跳过了单元测试(并且没有注意到这个错误);然后将代码提交给源代码控制,认为它是正确的。其他程序员也习惯于在跳过单元测试的同时构建代码。因此,该错误在几个星期内都没有被发现。但是,我确实执行了单元测试,并从源代码管理中收到了这个据称可以工作的代码,但它仍然包含错误。我没有向团队中的其他人询问该错误,因为当时我认为充分理解 Java 是我的责任,而不需要花费团队中其他程序员的时间,我认为这是我的误解,因为我认为其他人是在单元测试中没有收到错误。
【问题讨论】:
-
您似乎使用 bindSocketAddress 作为您想要发送数据包的主机,这是故意的吗?
-
@nos - 是的。 (这是我正在尝试构建和运行的代码库以克服此错误 - 我没有编写它 - 但是,这正是正在发生的事情,正如我从调试器中看到的那样,其中@987654330 @ 失败。)
-
嗯,这是一个逻辑错误——你需要弄清楚为什么写这个的人想要向 bindSocketAddress 发送消息。虽然将绑定地址配置为 0.0.0.0 确实有意义,因此您的套接字绑定到具有 IP 地址的所有接口,但尝试将数据包发送到 0.0.0.0 是没有意义的。也许您应该将绑定地址设置为实际的本地 IP 地址,以便您可以向自己发送数据包?
-
@nos - 我会问他们。现在 - 我已更改为
InetSocketAddress bindSocketAddress = new InetSocketAddress("localhost", service.getNetworkConfiguration().getBindSocketAddress().getPort());并且它成功了。我将修改我的问题以提及这一点 - 当我发现它是否/如何与 0.0.0.0 的初始 IP 收件人一起工作时,我将添加评论/答案。 -
这个问题是基于错误的假设。见更新。这个问题没有实际意义。