1

我有名为服务器、客户端和客户端 2 的 c# 可执行文件在同一个地址上相互发送消息。我通过它们即将到来的端口号来区分消息。

常规 run-1 服务器启动客户端加入,离开

run-2 服务器启动客户端 2 加入,离开

run-3 服务器启动客户端加入 client2 加入(问题来了),有时它从服务器获得回复,有时它只是挂起并且来自服务器的回复没有到达。

我正在使用 UDPClient 阻止 msg 传输例程。

当前解决方案:我从服务器发送相同的消息两次(希望至少第二次获得),因为它非常重要,我不再丢失这个消息。这种临时黑客的潜在失败是什么?

也请告诉我,如果我的 q?不完整,我会提供更多细节。

4

4 回答 4

4

简而言之,UDP可靠。UDP 的定义是没有办法告诉,更不用说保证一个数据包是否会到达它的目的地。

如果这些消息与您介绍的一样重要,我建议改用 TCP。这样,传输错误和失败会自动为您处理,您可以确保数据包到达目的地。

至于您的黑客攻击的潜在失败,您必须处理两个消息副本都到达的情况,以及不考虑两个副本都没有到达的情况。对我来说,在这种情况下,尝试重新发明轮子(发送确认消息、超时重试、处理重复收据)是不值得的。只需使用 TCP。

于 2011-10-19T05:48:02.577 回答
3

UDP 本身是不可靠的。您可以编写自己的代码以使其可靠地满足您的需求,但这取决于您自己。如果您想要可靠的流,请使用 TCP。

发送两次 UDP 数据包可能会减少数据包丢失的问题,但是您不能保证。我建议您实施一些确认系统,在客户端成功处理传入数据包后,客户端将数据包发送回服务器。服务器重复发送原始数据包,直到它看到确认。(您仍然应该对此有一些限制,否则它将永远尝试)

UDP 有用的情况是您不介意偶尔丢失数据包,但需要 UDP 可以带来的减少延迟(因为没有内置的重新传输)。例如游戏的状态信息,服务器通过 UDP 发送游戏数据。如果客户端没有收到数据包,它会在下一个数据包在几毫秒内到达时赶上。

于 2011-10-19T05:46:30.613 回答
2

如果可靠性胜过一切,请使用 TCP。但是,如果您需要低延迟和基于数据包的通信,那么您可以坚持使用 UDP,但实现更好的重传过程。

例如在 SIP(​​VOIP 协议)中,一般建议做以下事情:

  1. 设置一个计时器以在 500 毫秒 (T1) 时触发。
  2. 发送请求并启动计时器。
  3. 如果 T1 已过期而没有得到响应,则重新发送请求并加倍 T1。
  4. 执行 #3 直到您得到响应或直到 T1 达到 32 秒。
于 2011-10-19T05:55:43.703 回答
1

UDP 与网络堆栈中的较低级别允许的一样可靠;IP从根本上说是一种尽力而为的服务。这意味着您的数据不会被故意丢失或损坏,但不能保证。好消息是,在可能的通常情况下,通道的固有可靠性非常好,所以 UDP 可以。假设每个 UDP 数据报有概率 p 完好无损地到达接收者。在这种情况下,N 个数据包中至少有一个数据包完好无损地到达接收器的概率是 1-(1-p)^N。对于高 p(大于 90%),这会很快收敛到 1。但是,所有 N 个数据包中的数据总是有可能损坏。

您可以在传输层将可靠性保证构建到协议中;从某种意义上说,TCP 只是 UDP,已经执行了这个(和其他)额外的实现。许多 CS 网络课程涉及开发可靠的 UDP 协议。这里的好处是显而易见的:你获得了一定的(而不是很有可能,从统计学上讲)可靠性(假设你做对了)。

进入太多细节将是打开许多作者广泛撰写的一罐蠕虫。如果你想了解更多,我可以尝试推荐一些阅读。

于 2011-10-19T05:55:58.893 回答