DatagramSocket暂时停止接收数据包(Java)

时间:2011-11-29 16:24:58

标签: java sockets udp datagram

我已经在Lua中编写了一个插件,用于通过UDP数据包(512字节)将玩家信息发送到远程服务器,该服务器从数据包读取数据并将所有玩家信息聚合到xml文件中(然后可以所有玩家都在网上查看,以便他们可以看到彼此的当前状态。)

我用Java编程服务器使用DatagramSocket来处理传入的数据包,但是我注意到了一些奇怪的行为。经过一段时间后,DatagramSocket似乎暂时停止接受连接约10-12秒,然后再次恢复正常行为(没有抛出我可以看到的异常)。客户端发送数据包的频率与此行为发生的速度之间肯定存在关联。如果我增加客户端的更新频率,DatagramSocket将很快“失败”。

值得一提,但收到的每个数据包都会生成一个处理数据包中数据的线程。我在Linux上运行服务器,如果它有所作为!

有谁知道可能导致此类行为发生的原因?

安德鲁

3 个答案:

答案 0 :(得分:3)

UDP是一种绝对没有交付保证的网络协议。任何地方的任何网络组件(包括客户端和服务器PC本身)都可以决定因任何原因丢弃数据包,例如高负载或网络拥塞。

这意味着您必须稍微调整一下才能找出数据包丢失的位置。您可以使用wireshark之​​类的东西来查看数据包是否到达服务器。

如果可靠传送比低延迟更重要,请切换到TCP。如果您坚持使用UDP,则无论是否在此特定时间修复此特定问题,您都必须允许数据包丢失。

答案 1 :(得分:3)

我猜想你服务器端的接收缓冲区空间不足。

您可能想要重新审视您的设计:生成一个线程是一项相当昂贵的操作。对每个传入的数据包执行此操作将导致系统具有相对较低的吞吐量,这可以很容易地解释接收队列正在构建的原因。

另请参阅Specifying UDP receive buffer size at runtime in Linux

P.S。我相信你已经知道UDP不保证消息传递,所以我不会说明这一点。

答案 2 :(得分:1)

为每个UDP数据包启动一个线程是一个坏主意 TM 。 UDP服务器传统上被编码为简单的接收循环(毕竟你只需要一个套接字)。这样就可以避免线程,同步和其他所有开销。