DatagramSocket.send()在使用0.0.0.0时会出现“BindException: Cannot assign requested address”错误。

3
我正在对客户的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中的是0.0.0.0 - 我尝试了不同的端口(32168、22332、1234),但都出现了相同的错误。
DatagramSocket端口定义中出现的+100显然是有意为之的,并且这个测试套件已经成功地运行了很长时间,对于其他人来说,它也是这样。
我正在运行64位Windows 7。
我已经在本地机器上禁用了防火墙和杀毒软件,并且运行了netstat -a,但我没有看到我使用的任何端口在绑定端口列表中。
这可能是我的Windows配置问题,甚至是我的路由器问题吗?也许是我的Java配置有问题?任何建议都将不胜感激。
后续:当在CentOS 5.5虚拟机上运行时,我收到了完全相同的错误。虚拟机客户机正在运行在Windows 7主机上 - 共享其互联网连接。(桥接)
后续#2(见第4条评论):似乎将RECIPIENT设为0.0.0.0是无效的;事实上,在JDK(InetAddress.java)中的一条注释中说:未指定的地址(也称为任何本地或通配符地址)不能用作IP数据包的目标地址,其中通配符地址是0.0.0.0。我将代码更改为使用“localhost”(见第4条评论),这解决了问题。然而,上述代码可能有一个我不理解的有效原因;当我与代码的开发人员澄清时,我将发布后续或答案。
更新(2012年3月1日):事实上,在回顾过去时,所讨论的代码实际上只是前任程序员的一个错误。我的真正误解与问题的主题完全无关。
解释如下:每次我构建Java代码时,都会运行系统内置的相关单元测试。但在当时,我没有意识到可以构建源代码,同时跳过单元测试。事实证明,团队中的另一个程序员构建了代码(成功),但跳过了单元测试(并未注意到这个错误),然后将代码提交到源代码控制中心,认为它是正确的。其他程序员也习惯于在构建代码时跳过单元测试。因此,这个错误几周内没有被发现。但是,我确实执行了单元测试,并从源代码控制中接收到这个据说正常工作的代码,而它仍然包含这个错误。由于当时我认为理解Java足够对我负责,所以我没有向其他团队成员询问该错误,也假设其他人没有收到单元测试中的错误。

你似乎使用 bindSocketAddress 作为你想要“发送”数据包的主机,这是有意为之吗? - nos
@nos - 是的。(这是一个我正在尝试构建和运行的代码库,以便跨越此错误 - 我没有编写它 - 但正是这种情况发生了,因为我可以通过调试器逐步查看到 java.net.PlainDatagramSocketImpl.send() 失败的地方。) - Dan Nissenbaum
1
那么,这就是一个逻辑错误 - 你需要弄清楚为什么编写此代码的人想要将消息发送到bindSocketAddress。虽然将绑定地址配置为0.0.0.0可以使套接字绑定到具有IP地址的所有接口,但尝试向0.0.0.0发送数据包是没有意义的。也许你应该将绑定地址设置为实际的本地IP地址,这样你就可以向自己发送数据包了? - nos
@DanNissenbaum - 这个问题有什么更新吗?还是应该关闭它? - ziesemer
1
这个问题基于错误的假设。请参见更新。这个问题是无意义的。 - Dan Nissenbaum
显示剩余3条评论
1个回答

1
请看我的“更新”-这个问题已经无关紧要了。
请查看我长篇评论以获得更详细的解释。
我将保留这个问题,以防止在问题本身的主题与“更新”无关的情况下,有人发现它对他们有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接