38

我需要通过可能有损的网络将数据包从一台主机发送到另一台主机。为了最大限度地减少数据包延迟,我不考虑 TCP/IP。但是,我希望最大化使用 UDP 的吞吐量。要使用的 UDP 数据包的最佳大小应该是多少?

以下是我的一些考虑:

  • 网络中交换机的 MTU 大小为 1500。如果我使用大数据包,例如 8192,这会导致分片。丢失一个片段会导致整个数据包丢失,对吗?

  • 如果我使用较小的数据包,我会产生 UDP 和 IP 标头的开销

  • 如果我使用一个非常大的数据包,我可以使用的最大数据包是多少?我读到最大的数据报大小是 65507。我应该使用什么缓冲区大小来允许我发送这样的大小?这会有助于提高我的吞吐量吗?

  • 常见操作系统(例如 Windows、Linux 等)支持的典型最大数据报大小是多少?

更新:

一些数据的接收者是没有实现 TCP/IP 堆栈的嵌入式系统。

我知道这个地方到处都是非常坚持使用可用的东西的人。但我希望有更好的答案,而不是只关注 MTU。

4

7 回答 7

16

替代答案:小心不要重新发明轮子。

TCP 是数十年网络经验的产物。它所做的每一件事或几乎每一件事都有一个共鸣。它有几种大多数人不经常考虑的算法(拥塞控制、重传、缓冲区管理、处理重新排序的数据包等)。

如果您开始重新实现所有 TCP 算法,您可能会遇到一个(引用Greenspun 的第十条规则)“临时的、非正式指定的、漏洞百出的、缓慢的 TCP 实现”。

如果您还没有这样做,那么查看 TCP/UDP 的一些最新替代方案可能是个好主意,例如 SCTP 或 DCCP。它们是为 TCP 和 UDP 都不是很好匹配的领域而设计的,正是为了允许人们使用已经“调试过”的协议,而不是为每个新应用程序重新发明轮子。

于 2008-11-09T16:45:23.797 回答
14

找到理想数据包大小的最佳方法是完全按照 TCP 本身为找到理想数据包大小所做的工作:路径 MTU 发现

TCP 也有一个广泛使用的选项,双方告诉对方他们的 MSS(基本上,MTU 减去标头)是什么。

于 2008-11-09T16:29:24.267 回答
4

在 c# 中找到 mtu 的最简单的解决方法是发送 udp 数据包并将 dontfragment 标志设置为 true。如果它引发异常,请尝试减小数据包大小。这样做直到没有抛出异常。您可以从 1500 个数据包大小开始。

于 2010-11-11T03:59:47.707 回答
3

好吧,我有一个非 MTU 的答案给你。使用连接的 UDP 套接字应该为您加快速度。在 UDP 套接字上调用 connect 有两个原因。首先是效率。当您在未连接的 UDP 套接字上调用 sendto 时,会发生内核临时连接套接字、发送数据然后断开连接的情况。我读到一项研究表明,这在发送时占用了近 30% 的处理时间。调用 connect 的另一个原因是您可以获得 ICMP 错误消息。在未连接的 UDP 套接字上,内核不知道将 ICMP 错误传递给哪个应用程序,因此它们只会被丢弃。

于 2009-03-12T11:58:32.143 回答
3

要考虑的另一件事是某些网络设备不能很好地处理碎片。我们已经看到许多路由器丢弃分段的 UDP 数据包或太大的数据包。CesarB建议使用 Path MTU 是一个很好的建议。

最大吞吐量不仅仅由数据包大小驱动(尽管这当然有贡献)。最小化延迟和最大化吞吐量通常是相互矛盾的。在 TCP 中,您拥有 Nagle 算法,该算法(部分)旨在提高整体吞吐量。然而,一些协议(例如,telnet)经常禁用 Nagle(即,设置 No Delay 位)以改善延迟。

您对数据有一些实时限制吗?流式音频不同于推送非实时数据(例如,日志信息),因为前者受益于低延迟,而后者受益于增加的吞吐量和可能的可靠性。有可靠性要求吗?如果你不能丢失数据包并且必须有一个协议来请求重传,这将降低整体吞吐量。

有无数其他因素会影响这一点,并且(正如另一个响应中所建议的)在某些时候你会得到一个糟糕的 TCP 实现。话虽这么说,如果您想实现低延迟并且可以容忍使用 UDP 将整体数据包大小设置为 PATH MTU 的丢失(确保设置有效负载大小以考虑标头)可能是最佳解决方案(尤其是如果您可以保证UDP可以从一端到达另一端。

于 2008-11-09T17:09:01.567 回答
2

IP 标头 >= 20 字节,但大部分为 20,UDP 标头为 8 字节。这将为您留下 1500 - 28 = 1472 字节的数据。PATH MTU 发现在到达目的地的途中找到可能的最小 MTU。但这并不一定意味着,当您使用最小的 MTU 时,您将获得可能的最佳性能。我认为最好的方法是做一个基准测试。或者,也许您根本不应该关心最小的 MTU。网络设备可以很好地使用一个小的 MTU,并且也可以非常快速地传输数据包。而且它的价值在未来很可能会发生变化。因此,您无法发现它并将其保存在某个地方以供以后使用,您必须定期进行。如果我是你,我会将 MTU 设置为 1440 之类的东西并对应用程序进行基准测试...

于 2008-11-09T16:51:30.400 回答
1

即使交换机上的 MTU 是 1500,您也可能会遇到一些情况(例如通过 VPN 进行隧道传输),在数据包周围包裹一些额外的标头 - 您最好稍微减少它们,然后达到 1450 左右。

你能模拟网络并测试不同数据包大小的性能吗?

于 2008-11-09T16:17:33.197 回答