我有一个名为server,client和client2的c#可执行文件在同一个addr上互相发送消息。我通过它们来的端口号来区分消息。
常规跑1 服务器启动 客户加入,离开
运行-2- 服务器启动 客户端2加入,离开
运行-3- 服务器启动 客户加入 client2加入(这是问题),有时它会从服务器获得回复,有时它只是挂起而服务器的回复无法到达。
我正在使用UDPClient阻止msg传输例程。
当前解决方案:我从服务器发送相同的消息两次(希望至少第二次获得),因为它非常重要,我不再失去这个消息。什么可能是这种临时黑客的潜在垮台?
另外请告诉我,如果我的q?不完整我会提供更多细节。
答案 0 :(得分:4)
简而言之,UDP 不可靠。 UDP的定义是没有办法告诉,更不用说保证数据包是否会到达目的地。
如果这些消息和您一样重要,我建议您使用TCP。这样,您就可以自动处理传输错误和故障,并确保数据包能够到达目的地。
至于你黑客的潜在垮台,你必须处理邮件到达的两个副本的情况,以及不考虑副本到达的情况。对我来说,尝试重新发明轮子(发送确认消息,在超时时重试,处理重复的收据)在这种情况下是不值得的。只需使用TCP。
答案 1 :(得分:3)
UDP本身不可靠。您可以编写自己的代码以使其可靠地满足您的需求,但是您可以这样做。如果需要可靠的流,请使用TCP。
发送两次UDP数据包可以减少数据包丢失的问题,但是您无法保证。我建议你实现一些确认系统,客户端在成功处理传入数据包后将数据包发送回服务器。服务器重复发送原始数据包,直到它看到确认。 (你应该对此有一些限制,否则它会永远尝试)
UDP很有用的情况是你不介意偶尔会丢失数据包,但需要减少UDP带来的延迟(因为没有内置的重传)。例如,游戏的状态信息,其中服务器通过UDP发送游戏数据。如果客户端没有收到数据包,那么当下一个数据包在几毫秒内到达时它将会赶上。
答案 2 :(得分:2)
如果可靠性胜过一切,请使用TCP。但是,如果您需要低延迟和基于数据包的通信,那么您可以坚持使用UDP,但实现更好的重传过程。
例如,在SIP(VOIP协议)中,通常建议执行以下操作:
答案 3 :(得分:1)
UDP与网络堆栈中允许的较低级别一样可靠; IP基本上是一种尽力而为的服务。这意味着您的数据不会被故意丢失或损坏,但不保证。好消息是,在通常的情况下,通道的固有可靠性非常好,因此UDP可以。假设每个UDP数据报具有到达接收器未损坏的概率p。在这种情况下,使其未受损的N个分组中的至少一个的概率是1-(1-p)^ N.对于高p(大于90%),这很快收敛到1.但是,所有N个数据包中的数据总是有可能被破坏。
您可以在传输层为协议构建可靠性保证;从某种意义上说,TCP只是UDP,已经执行了这个(和其他)额外的实现。许多CS网络课程涉及开发可靠的UDP协议。这里的好处是显而易见的:你可以确定(而不是很可能,在统计学上说)可靠性(假设你做得对)。
进入更多细节将是打开许多作者广泛撰写的一堆蠕虫。如果您想了解更多信息,我可以尝试推荐一些阅读材料。