DatagramSocket随机停止接收DatagramPackets

问题描述 投票:0回答:2

我正在创建一个java多人游戏,它围绕着在LAN上的客户端和服务器之间不断发送数据报包。

随机地,客户端的DatagramSocket将停止从服务器接收数据包,因此客户端不会从服务器接收更新。

似乎DatagramSocket完全停止接收并且不会恢复接收。在每个客户端 - 服务器情况下都会发生此问题。

如果有人有任何想法,请说出我的想法!

Windows PC,Java 1.8

listening = true
PACKET_SIZE = 3096
buffer = new byte[PACKET_SIZE]
addr = InetAddress.getLocalHost()
port = new Random().nextInt(65536);
processor = Object

while(listening) {
    DatagramPacket p = new DatagramPacket(buffer, buffer.length, addr, port);

    try {
        socket.receive(p); // Code stops here
        processor.add(p);  // sends to queue to be processed

    } catch(IOException e) {
        e.printStackTrace();
    }

    buffer = new byte[PACKET_SIZE];

}

我希望程序无限期运行(假设服务器继续发送数据包)。然而,套接字在随机的时间量之后停止接收分组(每次不是相同的随机时间量)。

java networking udp
2个回答
2
投票

简答:远程服务器已经停止发送UDP数据报,或者网络由于某种原因已经停止提供它们。


我假设你有办法让服务器知道你用来监听数据报的随机端口和IP。如果服务器不使用相同的端口和IP发送,则UDP数据报将以静默方式消失。 (但是你说你的客户端代码有效,然后停止。这意味着IP和端口是正确的。)

我还假设您会告诉我们您是否获得异常并看到堆栈跟踪(!)

除此之外,我认为您的代码没有任何问题。如果我没有错过任何东西,这意味着问题是别的。我能想到的唯一其他解释是:

  1. 服务器已停止发送。 也许它已经崩溃了。 也许它已经“随机”切换到另一个端口。 也许它被锁定了,因为它正在等待一些不会发生的事情。例如,已丢失的响应消息的到达。
  2. 网络已停止传递UDP数据包。很难知道为什么: 这可能是由于在某些防火墙中实现了某种反DOS防御。 如果您的客户端位于NAT网关后面,并且您正在使用“打孔”来允许UDP数据包通过,那么“漏洞”可能已经超时。 (但是你说这是在局域网上,这意味着NAT不应该被涉及.NAT用于在两个网络之间的逻辑边界上使用的转换IP地址;例如专用网络< - >公共互联网。)

如建议的那样,尝试在两端使用Wireshark来查看服务器是否仍在发送UDP数据包并且仍然到达客户端。这将有助于您缩小问题范围。

请注意,如果您尝试通过UDP实现双向或多向通信,则需要允许随机删除邮件。在可能丢弃消息的所有情况下,您的应用程序级协议(使用UDP传输实现)需要能够检测1并从中恢复。如果你弄错了,其中一种可能就是协议“锁定”。


1 - 这通常涉及在某个级别实施超时。但是,只需在receive上设置超时(如另一个答案所示)并不能解决问题。


0
投票

一些帮助调试的建议:

  • 使用setSoTimeout(int milliseconds)为套接字设置合理的超时,并捕获SocketTimeoutException。服务器可能已经发送了一个数据包,由于某种原因它从未到过。如果服务器在发送另一个数据包之前等待响应,则客户端将无限期地等待。然后,您可以捕获SocketTimeoutException并将适当的数据包发送/重新发送到服务器。
  • 安装Wireshark以监控从服务器发送的数据包以及客户端收到的数据包。您应该能够看到数据包是否实际上是由服务器发送的,如果客户端从未接收到数据包,或者客户端是否实际收到了数据包,但客户端端出现了问题。
© www.soinside.com 2019 - 2024. All rights reserved.