2

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

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

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

有谁知道是什么导致这种行为发生?

安德鲁

4

3 回答 3

3

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

这意味着您必须深入研究才能找出数据包丢失发生的位置。您可以使用诸如wireshark 之类的东西来查看数据包是否完全到达服务器。

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

于 2011-11-29T16:28:26.587 回答
3

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

您可能想重新审视您的设计:生成线程是一项非常昂贵的操作。对每个传入的数据包都这样做会导致系统吞吐量相对较低,这可以很容易地解释为什么接收队列正在建立。

另请参阅在 Linux 中在运行时指定 UDP 接收缓冲区大小

PS 我相信你已经知道 UDP 不保证消息传递,所以我不会费力。

于 2011-11-29T16:29:17.087 回答
1

为每个 UDP 数据包启动一个线程是一个 Bad Idea TM。UDP 服务器传统上被编码为简单的接收循环(毕竟你只需要一个套接字)。通过这种方式,您可以避免线程、同步等所有开销。

于 2011-11-29T16:30:50.040 回答