Sockets UDP根本不可靠?

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

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

UDP本质上是不可靠的,因为:

  • UDP数据包可能丢失,并且
  • UDP协议不提供任何机制来判断数据包是否丢失或重新发送
为什么数据包会被丢弃

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

  • 数据包可能被错误路由
  • 数据包可能被防火墙“吃掉”
  • 由于网关中的拥塞,数据包可能会被丢弃
  • 数据包可能由于端点处的拥塞而被丢弃,或者
  • 数据包可能由于网络级问题而丢失;e、 g.碰撞或传输错误
包的大小有问题吗

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

参考文献:

因此,大型UDP数据包丢失的概率更大

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

我应该如何使它可靠

这些事情可能会有所帮助:

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

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

UDP是一种天生不可靠的协议,但它比通常更不可靠可能是有原因的。你有关于实际下降率的统计数据吗?我没有任何统计数据。但它是如此随机。数据报大小会影响丢弃率吗?可能是的,尽管800字节相当小。如果没有下降率的统计数据,就不可能确定你的损失是预期的还是不同寻常的。无线链路是相当有损的,但像TCP这样的协议可以弥补这一点。UDP是一种“火而忘却”的方式。这样你就不会获得绝对的可靠性,但是,如果在这种情况下丢包率对你来说合适的话,那当然是一种方法。否则,您需要在协议中进行某种形式的确认,或者只是执行TCP。WiFi上的广播(和多播)根本无法正常工作:您的链接表示数据包>MTU是分段的(在以太网上,与您的链接一样,通常是1500),您从何处获得534字节?@markmnl-IP数据包所需的最小MTU是576。扣除UDP/IP头大小…感谢您的详细回答。我已经解决了这一问题,为每个数据包发送一个确认,然后重试,直到数据包通过,它们之间有500毫秒的延迟。它比单纯的方法工作得更好。如果我们在UDP端口上延迟一段时间接收数据包,操作系统会丢弃数据包吗?我认为不会。但如果超过套接字的内核缓冲,它将丢弃UDP消息;i、 如果你有太多未读的信息。