我有一个客户端需要在特定端口上侦听传入的UDP广播消息。我通过使用setSoTimeout为1500ms初始化绑定到端口的DatagramSocket对象来实现此目的。
while (true) {
try{
DatagramSocket datagramSocket = new DatagramSocket(PORT);
byte[] buffer = new byte[BUFF_LEN];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
datagramSocket.receive(packet);
[handoff packet to internal buffer to await processing]
} catch (SocketTimeoutException timeout) {
...
} catch [other exceptions]
}
这是漂亮的教科书,一切正常;但是在最近的一次网络负载测试中,我发现我的应用程序没有收到某些数据报,问题越严重,网络就越拥挤。
进一步挖掘我发现每次调用.receive()时都会触发超时 - 几乎就好像没有任何东西到达端口。 然而,在同一台机器上运行Wireshark表明这不是真的,并且预期大小和内容的格式良好的数据包正常照常到达。不知何故,数据报并没有找到进入应用层的方式。
立即减少网络流量可以缓解此问题,Java应用程序可以像往常一样立即接收和处理数据包。
任何人都可以了解这里可能存在的问题,或者我可以做些什么来解决这个问题?
非常感谢。
答案 0 :(得分:1)
软件防火墙上的UDP泛洪保护可能吗?
此外,UDP是一种不可靠的协议设计。可能是网络层因负载而丢弃数据包。
答案 1 :(得分:0)
如果数据包到达主机,如果套接字发送缓冲区已满,主机仍然可以丢弃它们,这在应用程序无法跟上输入时发生。
答案 2 :(得分:0)
我经常用Java编程,所以也许我在这里遗漏了一些东西,但为什么你在循环中调用new DatagramSocket
?似乎这会为每个数据报创建一个新的套接字,这将很快耗尽系统资源。