【问题标题】:Improving UDP reliability提高 UDP 可靠性
【发布时间】:2010-12-29 12:47:20
【问题描述】:

我正在构建一个基于 UDP 的小型服务器。服务器基于 .Net 并使用它自己的 Socket 类。我通过 ReceiveMessageFromAsync 和异步发送使用完成端口。

我的问题是我失去了大约 5%-10% 的流量。现在我知道这是正常的,但是有什么方法可以改善这个统计数据吗?

【问题讨论】:

  • 为什么选择 UDP 而不是 TCP?
  • 不是我的选择。但我们致力于此。
  • 这是在专用网络上吗?
  • @kevpie 是的。在机器内部,局域网也是......
  • 它可以是缓冲区/硬件相关的。 stackoverflow.com/questions/2402944/…

标签: .net networking udp reliability


【解决方案1】:

在将您自己的可靠性层置于 UDP 之上之前,您可能想查看此问题的答案...What do you use when you need reliable UDP?

或者,您可以尝试通过在开始接收之前设置适当的套接字选项,使套接字的发送和接收缓冲区尽可能大,从而增加通过的数据量。

【讨论】:

  • 增加缓冲区有所帮助。
  • 如果您使用异步读取,然后一次发布多个,这也可能会有所帮助...
【解决方案2】:

确保您发送的 UDP 数据报不大于路径 MTU(通常不超过 ~1400 字节,有时更小)。这样的数据包将被分割成多个 IP 数据包并在目的地重新组合 - 如果这些片段中的任何一个丢失,那么整个 UDP 数据报将被丢弃。

这对数据包丢失率有放大效应 - 下表显示了 UDP 数据报丢失率如何随着用于承载它的片段数量的增加而急剧上升:

Underlying Fragment Loss Rate: 1.00%

Fragments   UDP Datagram Loss Rate
--------------------------------------
1           1.00%
2           1.99%
3           2.97%
4           3.94%
5           4.90%
6           5.85%
7           6.79%
8           7.73%
9           8.65%
10          9.56%
15          13.99%
20          18.21%
30          26.03%
40          33.10%

【讨论】:

    【解决方案3】:

    用于套接字的 Windows 体系结构似乎不利于良好的 UDP 性能,因为从内核通过协议处理程序将数据包缓冲区多次复制到应用程序。如果开发人员需要合理的数据报性能(例如实现可靠的 UDP 协议),MSDN 似乎更愿意将开发人员指向 Winsock Kernel (WSK),而不是以前的 Transport Driver Interface (TDI)。

    但是,它可能只是适用于您的 NIC 硬件的非一流 Windows 驱动程序,因为我看到 Linux 与 Broadcom 硬件的性能非常好,但不到 Windows 的 25%。我可以看到其中的一些原因是由于缺少传输中断合并,Windows 性能监控始终报告传输的合并为 0,但接收的合并范围可变。在 Linux 上,我可以调整合并并看到明显的性能变化。来自 Broadcom 的驱动程序软件似乎仅在以后的硬件版本中支持传输合并。

    合并意味着数据包被分批发送进出 NIC,批处理数据包通常意味着 CPU 使用率较低,并且由于缓冲区满或其他系统活动而丢弃的可能性较小。

    因此,虽然更改操作系统看起来不切实际,但您可以尝试不同的硬件以尽量减少有限驱动程序的影响。

    【讨论】:

      【解决方案4】:

      您所能做的几乎就是与 TCP 使用的一般顺序相同的东西——跟踪接收到的数据包,然后将某些数据发送回 ACK/NAK 数据包以重新发送未到达的数据包。

      【讨论】:

      • 我有点这样做。这是题外话。失去流量对我来说不是一个真正的问题,我只是想尽量减少失去的流量。
      • @acron:不,它没有。如果您完全与 TCP 一样,它可能会否定这一点——但仍有许多变化的空间,可以保持几乎正常 UDP 的延迟,同时提供几乎 TCP 的可靠性。一种可能的来源是查看旧的基于调制解调器的文件传输协议(例如,ymodem、ymodem-G、zmodem 等)。这些协议都有效,并且大多数都经过了高度优化,以防止像 TCP 那样增加延迟(在更复杂的代价,尤其是在 zmodem 的情况下)。
      • @Hellfrost:您可以做很多事情来减少数据包丢失。如果您非常想这样做,您可以使用路由器表来尝试找到更可靠的链接,但是 1)它很复杂,以及 2)在 Internet 上,您通常无法控制足够的路由来产生显着差异无论如何。
      【解决方案5】:

      减少数据包丢失的另一个方面是调节发送数据包的速率。如果您发送数据的速度快于路径上的瓶颈点可以处理的速度,则这将表现为丢包。即使您的平均数据速率非常低,您仍可能会快速连续发送数据包。

      TCP 通过将未确认的未确认数据字节数限制为一个称为拥塞窗口的值来处理此问题。拥塞窗口开始时很小,然后慢慢增加,直到发生丢包,此时它会缩小(如果丢包继续发生,则逐渐缩小)。如果在你的协议中通知发送者丢包,你可以实现类似的东西。

      【讨论】:

        猜你喜欢
        • 2017-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-06
        • 1970-01-01
        • 2011-09-25
        • 2011-03-03
        • 2011-05-09
        相关资源
        最近更新 更多