3

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

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

4

5 回答 5

4

在将您自己的可靠性层置于 UDP 之上之前,您可能想查看此问题的答案……当您需要可靠的 UDP 时,您会使用什么?

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

于 2010-12-14T15:21:12.020 回答
2

确保不发送大于路径 MTU 的 UDP 数据报(通常不超过 ~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%
于 2010-12-15T03:39:44.593 回答
1

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

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

合并意味着数据包被批量发送进出 NIC,批处理数据包通常意味着更低的 CPU 使用率,并且由于缓冲区满或其他系统活动而丢失的机会更少。

So whilst it looks like it would be impractical to change OS you can try different hardware to minimize the impact of limited drivers.

于 2010-12-29T04:47:20.307 回答
0

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

于 2010-12-14T14:05:22.417 回答
0

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

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

于 2010-12-15T23:10:46.603 回答