DatagramSocket随机停止接收DatagramPackets

时间:2019-04-20 23:35:47

标签: java networking udp

我正在创建一个Java多人游戏,该游戏解决了局域网中客户端和服务器之间不断发送DatagramPackets的问题。

随机地,客户端的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];

}

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

2 个答案:

答案 0 :(得分:2)

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


我假设您可以通过某种方式让服务器知道您正在用来侦听数据报的随机端口和IP。如果服务器不使用相同的端口和IP进行发送,则UDP数据报将自动消失。 (但是您说您的客户端代码会工作一段时间然后停止。这意味着IP和端口是正确的。)

我还假设如果您遇到异常并看到stacktraces(!)

,您会告诉我们

除上述内容外,我发现您的代码没有错。如果我没有错过任何东西,那意味着问题出在别的东西上。我能想到的唯一其他解释是:

  1. 服务器已停止发送。

    • 也许它已经崩溃了。
    • 也许它“随机地”切换到了另一个端口。
    • 可能是因为它正在等待不会发生的事情而被锁定。例如,丢失的响应消息的到达。
  2. 网络已停止传递UDP数据包。很难知道为什么:

    • 这可能是由于某些防火墙中实施了某种反DOS防御所致。
    • 如果您的客户端位于NAT网关后面,并且您正在使用“打孔”功能来允许UDP数据包通过,则“打孔”可能已超时。 (但是您说这是在LAN上,这意味着不应该涉及NAT。NAT用于在两个网络之间的逻辑边界上转换IP地址;例如,专用网络<->公共Internet。)

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

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


1-这通常涉及在某种程度上实现超时。但是只是receive上设置超时(如另一个答案所建议)不能解决问题。

答案 1 :(得分:0)

一些有助于调试的建议:

  • 使用setSoTimeout(int ms)为套接字设置一个合理的超时,并捕获SocketTimeoutException。服务器可能已经发送了一个数据包,并且由于某种原因它从未到达。如果服务器在发送另一个数据包之前正在等待响应,则您的客户端将无限期等待。然后,您可以捕获SocketTimeoutException并将适当的数据包发送/重新发送到服务器。

  • 安装Wireshark监视从服务器发送的数据包以及客户端接收的数据包。您应该能够查看该数据包是否实际上是由服务器发送的,或者客户端从未收到过该数据包,还是客户端实际上已接收到该数据包,但是客户端端出了点问题。

    < / li>