TCP连接的最大数据包大小


196

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


24
TCP是基于流的。您担心单个数据包是否有特定原因?
Matti Virkkunen 2010年

27
因为它下面的层是基于数据包的...典型实现->第1层-以太网PHY,第2层-以太网MAC(MAC数据包定义,第3层-Internet协议(IP数据包定义),第4层-TCP(传输控制协议) )-在其下使用基于分组的服务

2
没有“ TCP数据包”之类的东西。有TCP ,其长度由32位字描述,它们包含在IP数据包内或跨IP数据包,其长度以16位描述。还有以太网帧,其中包含所有这些内容。您在问以下哪些内容?无论如何,如果您使用的是TCP,则不必以任何方式担心它们中的任何一个:TCP和IP会为您全力以赴。
罗恩侯爵,

Answers:


178

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

例如,以太网的MTU(最大传输单元)为1500字节。某些类型的网络(例如令牌环)的MTU较大,某些类型的MTU较小,但是每种物理技术的值都是固定的。


15
“但是每种物理技术的价值都是固定的” –这不是事实。以太网以前的最大MTU为1500,但您可以使用较低的MTU。随着巨型帧的出现,没有真正的指定最大值,并且最大值取决于硬件和驱动程序。
WhirlWind 2010年

4
@Whirl:是的,它们是可配置的,但通常不是。“可配置的”是主观的,因为这样做必须深入内核。在应用程序级别(这似乎是OP所处的位置)上,这不是一件可以修改的事情。
以太2010年

3
@HiroProtagonist:最大值为1500,因此拥有600也就不足为奇了。
尼古拉斯·拉乌尔

28
为什么有64K(65535字节)的限制?因为TCP标头中的“窗口大小”属性只有16位。我只想提一下,可能会在某个时候帮助某人.....很棒的答案@Ether!
Cacho Santa

2
同样,可以通过使用窗口缩放来增强它。在这种情况下,最大数量为1 GiB
Martin Melka

86

这是一个很好的问题,实际上我在工作中经常遇到这个问题。有很多“技术上正确的”答案,例如65k和1500。我已经做了很多工作来编写网络接口,并且使用65k很愚蠢,而1500也会给您带来麻烦。我的工作在许多不同的硬件/平台/路由器上进行,老实说,我开始的地方是1400字节。如果您需要的数字超过1400,则可以开始逐步提高,可能会达到1450,有时甚至达到1480'ish?如果您需要的更多,那么您当然需要分成2个数据包,其中有几种显而易见的方法。

问题是您正在谈论创建数据包并通过TCP将其写出,但是当然要添加标头数据,依此类推,因此您有“负担”,使您达到1500或更高。很多硬件都有较低的限制。

如果“推”它,可能会发生一些非常奇怪的事情。截断的数据,很明显,或者删除的数据很少见。损坏的数据也很少,但确实会发生。


为什么GET请求平均约600个字节?

10
您的意思是64K,而不是65K。我不知道“我的起始地址是1400字节”是什么意思。您不必担心TCP API中的数据包大小。它负责确定和观察路径MTU。send()如果方便的话,没有理由不能将2G写入一个。
2013年

19
1480'ish应该是1460。IP标头和TCP标头至少占用20个字节(除非使用了可选的标头字段),因此(非超大帧)以太网的最大值为1500 - 20 -20 = 1460
尤金·别列索夫斯基

2
我通过Wireshark看到服务器发送了大数据包(超过1400字节),而客户端接收到的数据包却被分解为最大为1400个字节的几个数据包。谁负责拆包?@Nektario ...?
2015年

2
@EugeneBeresovsky与可选标头多数民众赞成在+ 40多字节,但它是可变的,因此1420似乎是限制。在1400的建议下,您会得到一些填充。我将使用1408,因为它可以被128整除
Garet Claborn

22

在应用程序级别,应用程序使用TCP作为面向流的协议。反过来,TCP会进行细分,并抽象出处理不可靠IP数据包的细节。

TCP处理段而不是数据包。每个TCP段都有一个包含在TCP标头中的序列号。在TCP段中发送的实际数据是可变的。

在某些可以使用的OS上有一个名为getsockopt的值,称为TCP_MAXSEG,该值可检索最大TCP段大小(MSS)。但是,并非所有操作系统都支持它。

我不确定您要做什么,但是如果您想减小已使用的缓冲区大小,还可以考虑:SO_SNDBUF和SO_RCVBUF。


我想知道是否可以将TCP用作消息队列,是否可以将所有消息放入一个大型TCP数据包中?
CMCDragonkai 2015年


4

TCP API中没有数据包。

基础协议中经常有数据包,例如TCP通过IP完成时,您可能会对此不感兴趣,因为它们与用户无关,只是您可能不感兴趣的非常微妙的性能优化(根据问题的表述)。

如果您问send()一个API调用中最多可以有多少个字节,那么这取决于实现和设置。您通常会调用send()来获取不超过几千字节的数据块,并随时准备让系统拒绝完全或部分接受它,在这种情况下,您将必须手动管理拆分成较小的数据块才能将数据馈送到TCP send()API。


8
TCP具有数据包以及数据包头,其中一部分与IP头重叠。仅仅因为您不应该看到它并不意味着它不存在。TCP 始终通过IP进行。如果没有IP,就无法做到,因为标题重叠。
WhirlWind 2010年

23
@WhirlWind TCP具有段。IP有数据包。
洛恩侯爵,

1
TCP有段(或称它们为包,没关系)。TCP API没有数据包。
Pavel Radzivilovsky

13
@NathanLong的危害是您造成不必要的混乱。TCP有网段,UDP有数据报,IP有数据包,以太网有帧,...
Lorne Marquis 2015年

1
@Chexxor那么,您将使用什么语言来描述以太网帧内IP数据包内的TCP段?当这些事情的作者为使用不同的术语而烦恼时,根本不需要通过在不同的事物上使用相同的术语来混淆问题。
罗恩侯爵

3

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

仅当MTU在网络上至少达到这么大时,才是这种情况。TCP可能会使用路径MTU发现来减少您的有效MTU。

问题是,你为什么在乎?


6
这样只会在第一个链接上获得最大的数据包大小。据我所知,该路由上的任何其他节点都不允许不喜欢大数据包,并且它可能会在路径上的任何地方被拆分。
Matti Virkkunen 2010年

是的,没错...所以您的问题很好-为什么要这么做?
WhirlWind 2010年

我想通过局域网连接传输视频/图像
Alexa 2010年

1
由于TCP是面向流的,为什么这很重要?
WhirlWind

3

如果您使用的是Linux计算机,则“ ifconfig eth0 mtu 9000 up”是用于设置接口的MTU的命令。但是,我不得不说,如果网络传输不稳定,那么大的MTU会有一些缺点,并且可能会使用更多的内核空间内存。


3

似乎大多数Internet上的网站都使用1460字节作为MTU的值。有时是1452,如果您使用的是VPN,则IPSec标头的丢弃量甚至会更多。

默认窗口大小变化很大,最大为65535字节。我使用http://tcpcheck.com查看自己的源IP值并检查其他Internet供应商正在使用什么。


2

一种解决方案是将套接字选项TCP_MAXSEG(http://linux.die.net/man/7/tcp)设置为对基础网络“安全”的值(例如,设置为1400以在以太网上安全),然后在发送系统调用中使用较大的缓冲区。这样,可以减少昂贵的系统调用。内核将拆分数据以匹配MSS。

这样,您可以避免数据被截断,并且您的应用程序不必担心小缓冲区。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.