【问题标题】:UDP is not reliable at all?UDP根本不可靠?
【发布时间】:2014-06-18 16:41:33
【问题描述】:

我设计了一个系统,在该系统中我使用 UDP 向连接到同一接入点的一些客户端发送广播消息。我正在使用接入点连接服务器和所有其他客户端。问题在于广播。当我向客户端广播一条 800 字节的消息时,接收是完全随机的。有时客户端能够获取消息,有时则不能。我尝试多次广播它,以便至少有一个通过并到达所有客户。但即使这样有时也不起作用。为什么数据包会被丢弃?数据包大小有问题吗?我应该如何使它可靠?哪些因素可能导致这种情况? 我有 40-50 个客户端连接到 AP。接入点专门用于此应用程序,并且没有互联网连接。

【问题讨论】:

  • UDP 本质上是一种不可靠的协议,但它比平时更不可靠可能是有原因的。你有一些关于实际掉率的统计数据吗?
  • 我没有任何统计数据。但它是如此随机。数据报大小会影响丢弃率吗?
  • 可能是的,尽管 800 字节非常小。如果没有关于掉率的统计数据,就无法确定您的损失是预期的还是异常的。无线链路的损耗相当大,但 TCP 等协议将弥补这一点。 UDP 就是一劳永逸。
  • 这样你不会获得绝对的可靠性,但可以肯定的是,如果在这种情况下你的掉率合适,那是一种方法。否则你需要在你的协议中进行某种确认,或者只做 TCP。
  • 通过 WiFi 进行广播(和多播)根本无法正常工作:superuser.com/questions/695813/…

标签: sockets networking network-programming udp broadcast


【解决方案1】:

从某种意义上说,UDP 本质上是不可靠的:

  • UDP 数据包可能丢失,并且
  • UDP 协议没有提供任何机制来判断数据包是否丢失或重新发送。

为什么数据包会被丢弃?

一般来说,可能的原因有很多:

  • 数据包可能被错误路由,
  • 数据包可能会被防火墙“吃掉”,
  • 可能由于网关拥塞而丢弃数据包,
  • 数据包可能由于端点拥塞而被丢弃,或者
  • 数据包可能由于网络级别的问题而丢失;例如冲突或传输错误。

数据包大小有问题吗?

是的。如果 UDP 数据包太大,可能需要对其进行分段(在 IP 数据包级别)。如果其中任何一个片段丢失,则接收方无法重新组装数据包,整个 UDP 数据包将丢失。 (没有重新传输丢失片段的机制。)

参考:http://pcvr.nl/tcpip/udp_user.htm#11

因此,较大的 UDP 数据包丢失的可能性更大。

请注意,当 IP 数据包大小超过链接的 MTU 时,会发生碎片。对于以太网链路,MTU 通常约为 1500 个八位字节或更多。但是 IPv4 规范允许 MTU 低至 576 个八位字节。如果减去 IP 和 UDP 标头的大小,则在可以进行分段之前,UDP 数据包有效负载的最小大小为 534 个八位字节。

我应该如何使它可靠?

这些东西可能有帮助:

  • 选择不会导致碎片的最大 UDP 数据包大小。
  • 实施您的软件以尽快读取数据包...以避免数据包被接收操作系统丢弃。
  • 避免通过(可能)拥塞的网络链接发送 UDP 数据包。
  • 避免在太短的时间内发送太多数据包。

但是在上述意义上,没有什么能使 UDP 可靠。该协议本质上是不可靠的。如果您想要可靠性,请使用 TCP 或在应用程序协议级别实现您自己的可靠性机制。前者可能是更好的方法。

【讨论】:

  • 您的链接显示数据包 > MTU 是分段的(在以太网上,如您的链接中通常为 1500),您从哪里获得 534 个字节?
  • @markmnl - IP 数据包所需的最小 MTU 为 576。减去 UDP/IP 标头大小 ...
  • 感谢您的详细解答。我已经通过为每个数据包发送确认并重试直到数据包通过它们之间的 500 毫秒延迟来解决它。它比天真的方法效果更好。
  • 如果我们延迟一段时间在 UDP 端口上接收数据包,操作系统会丢弃数据包吗?
  • 我认为不会。但是如果超出了套接字的内核缓冲,它将丢弃 UDP 消息;即如果您有太多未读消息。
猜你喜欢
  • 1970-01-01
  • 2012-05-06
  • 2011-09-25
  • 2011-03-03
  • 2011-05-09
  • 2017-05-10
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多