TCP连接的最大数据包大小

Ale*_*exa 181 networking tcp

TCP连接的最大数据包大小是多少,或者如何获得最大数据包大小?

Eth*_*her 167

TCP数据包大小的绝对限制是64K(65535字节),但实际上这远远大于您将看到的任何数据包的大小,因为较低层(例如以太网)具有较低的数据包大小.

例如,以太网的MTU(最大传输单元)为1500字节.某些类型的网络(如令牌环)具有更大的MTU,并且某些类型具有更小的MTU,但是每个物理技术的值是固定的.

  • 为什么64K(65535字节)的限制?因为TCP标头中的窗口大小属性仅为16位.我只是想提一下,有时可以帮助某人.....很棒的答案顺便说一句@Ether! (20认同)
  • "但每种物理技术的价值都是固定的" - 这不是真的.以太网过去的最大MTU为1500,但您可以使用较低的MTU.随着巨型帧的出现,没有真正指定的最大值,最大值取决于硬件和驱动程序. (14认同)
  • @Whirl:是的,它们是可配置的,但通常它们不是; "可配置"是主观的,因为人们必须深入研究内核才能这样做.这不是人们可以在应用程序级别修改的东西,这是OP似乎所处的位置. (4认同)
  • @HiroProtagonist:1500是最大的,所以有600并不奇怪. (3认同)
  • 此外,可以通过使用窗口缩放来提升它.在这种情况下,最大值为1 GiB (2认同)

Nek*_*ios 79

这是一个很好的问题,我实际上在工作中遇到了很多.有很多"技术上正确"的答案,如65k和1500.我已经做了很多编写网络接口的工作,使用65k是愚蠢的,1500也可以让你遇到大麻烦.我的工作涉及很多不同的硬件/平台/路由器,说实话,我开始的地方是1400字节.如果你需要超过1400你可以开始上升,你可能会到1450年,有时到1480年?如果您需要更多,那么当然您需要拆分为2个数据包,其中有几个明显的方法.

问题是你正在谈论创建一个数据包并通过TCP写出来,但当然还有标题数据等等,所以你有"行李"让你达到1500或更高......还有一个很多硬件都有下限.

如果你"推它",你可以得到一些非常奇怪的事情.显然,截断的数据或丢失的数据我很少见到.损坏的数据也很少但肯定会发生.

  • 你的'1480'ish`应该是'1460`.IP报头和TCP报头至少占用20个字节(除非使用可选的报头字段),因此(非巨型帧)以太网的最大值为"1500 - 20 -20 = 1460". (16认同)
  • 你的意思是64K,而不是65K.我不知道你的意思是'我开始的地方是1400字节'.您不必担心TCP API中的数据包大小.它负责确定和观察路径MTU.如果方便的话,没有理由不能在一个`send()`中写2G. (10认同)
  • 我通过wireshark看到服务器发送大数据包(超过1400字节),客户端接收到的数据包被反汇编为最少1400字节的数据包.谁负责拆解数据包?@Nektario ......? (2认同)
  • @EugeneBeresovsky 以及可选的标头 + 最多 40 个字节,但它是可变的,因此 1420 似乎是限制。建议 1400,你会得到一点填充。我会用 1408 因为它可以被 128 整除 (2认同)

Bri*_*ndy 20

在应用程序级别,应用程序使用TCP作为面向流的协议.TCP依次具有段并且抽象出使用不可靠IP分组的细节.

TCP处理段而不是数据包.每个TCP段具有包含在TCP头部内的序列号.TCP段中发送的实际数据是可变的.

某些操作系统支持getsockopt的值,您可以使用这个值称为TCP_MAXSEG,它检索最大TCP段大小(MSS).但是并非所有操作系统都支持它.

我不确定你要做什么,但如果你想减少使用的缓冲区大小,你也可以考虑:SO_SNDBUF和SO_RCVBUF.


Rob*_*obs 6

根据http://en.wikipedia.org/wiki/Maximum_segment_size,网络上IPV4数据包的默认最大大小为536个八位字节(大小为8位的字节).请参阅RFC 879


Whi*_*ind 5

一般来说,这取决于连接所使用的接口。您可以使用 ioctl() 来获取 MTU,如果是以太网,通常可以通过从中减去硬件标头的大小来获得最大数据包大小,对于没有 VLAN 的以太网,该大小为 14。

仅当整个网络中的 MTU 至少如此大时才会出现这种情况。TCP 可能会使用路径 MTU 发现来减少有效 MTU。

问题是,你为什么关心?

  • 这只会让您获得第一个链接上的最大数据包大小。据我所知,路径上的任何其他节点都可以不喜欢大数据包,并且它可能会在路径上的任何地方被分割。 (7认同)
  • 既然 TCP 是面向流的,那么为什么这很重要呢? (2认同)

Pav*_*sky 5

TCP API 中没有数据包。

底层协议中经常有数据包,比如当 TCP 通过 IP 完成时,你不感兴趣,因为它们与用户无关,除了你可能不感兴趣的非常微妙的性能优化(根据问题的表述)。

如果您询问send()在一次 API 调用中可以使用的最大字节数是多少,那么这取决于实现和设置。您通常会为最大几千字节的块调用 send() ,并随时准备好让系统拒绝完全或部分接受它,在这种情况下,您将不得不手动管理拆分为更小的块以将您的数据输入到TCP 发送() API。

  • @WhirlWind TCP 有 *segments.* IP 有数据包。 (25认同)
  • @NathanLong 危害是你造成了不必要的混乱。TCP 有段,UDP 有数据报,IP 有数据包,以太网有帧,...... (16认同)
  • TCP 有数据包,以及数据包头,其中一部分与 IP 头重叠。仅仅因为你不应该看到它并不意味着它不存在。TCP * 总是 * 通过 IP 完成。没有 IP 就不能这样做,因为标头重叠。 (8认同)
  • TCP 有段(或称它们为数据包,没关系)。TCP API 没有数据包。 (3认同)
  • @Chexxor 那么,您将使用什么语言来描述以太网帧内 IP 数据包内的 TCP 段?没有必要通过对不同的事物使用相同的术语来混淆这个问题,因为这些事物的作者为了使用不同的术语而遇到很多麻烦。 (2认同)