TCP连接的最大数据包大小是多少?如何获得最大数据包大小?
TCP连接的最大数据包大小是多少?如何获得最大数据包大小?
Answers:
TCP数据包大小的绝对限制为64K(65535字节),但是实际上这远远超出了您将看到的任何数据包的大小,因为较低的层(例如,以太网)具有较低的数据包大小。
例如,以太网的MTU(最大传输单元)为1500字节。某些类型的网络(例如令牌环)的MTU较大,某些类型的MTU较小,但是每种物理技术的值都是固定的。
这是一个很好的问题,实际上我在工作中经常遇到这个问题。有很多“技术上正确的”答案,例如65k和1500。我已经做了很多工作来编写网络接口,并且使用65k很愚蠢,而1500也会给您带来麻烦。我的工作在许多不同的硬件/平台/路由器上进行,老实说,我开始的地方是1400字节。如果您需要的数字超过1400,则可以开始逐步提高,可能会达到1450,有时甚至达到1480'ish?如果您需要的更多,那么您当然需要分成2个数据包,其中有几种显而易见的方法。
问题是您正在谈论创建数据包并通过TCP将其写出,但是当然要添加标头数据,依此类推,因此您有“负担”,使您达到1500或更高。很多硬件都有较低的限制。
如果“推”它,可能会发生一些非常奇怪的事情。截断的数据,很明显,或者删除的数据很少见。损坏的数据也很少,但确实会发生。
send()
如果方便的话,没有理由不能将2G写入一个。
1480'ish
应该是1460
。IP标头和TCP标头至少占用20个字节(除非使用了可选的标头字段),因此(非超大帧)以太网的最大值为1500 - 20 -20 = 1460
。
在应用程序级别,应用程序使用TCP作为面向流的协议。反过来,TCP会进行细分,并抽象出处理不可靠IP数据包的细节。
TCP处理段而不是数据包。每个TCP段都有一个包含在TCP标头中的序列号。在TCP段中发送的实际数据是可变的。
在某些可以使用的OS上有一个名为getsockopt的值,称为TCP_MAXSEG,该值可检索最大TCP段大小(MSS)。但是,并非所有操作系统都支持它。
我不确定您要做什么,但是如果您想减小已使用的缓冲区大小,还可以考虑:SO_SNDBUF和SO_RCVBUF。
根据http://en.wikipedia.org/wiki/Maximum_segment_size,网络上IPV4数据包的默认最大大小为536个八位字节(8位字节)。参见RFC 879
TCP API中没有数据包。
基础协议中经常有数据包,例如TCP通过IP完成时,您可能会对此不感兴趣,因为它们与用户无关,只是您可能不感兴趣的非常微妙的性能优化(根据问题的表述)。
如果您问send()
一个API调用中最多可以有多少个字节,那么这取决于实现和设置。您通常会调用send()来获取不超过几千字节的数据块,并随时准备让系统拒绝完全或部分接受它,在这种情况下,您将必须手动管理拆分成较小的数据块才能将数据馈送到TCP send()API。
通常,这将取决于连接所使用的接口。您可能可以使用ioctl()来获取MTU,如果它是以太网,则通常可以通过减去其中的硬件标头来获得最大数据包大小,对于没有VLAN的以太网,它为14。
仅当MTU在网络上至少达到这么大时,才是这种情况。TCP可能会使用路径MTU发现来减少您的有效MTU。
问题是,你为什么在乎?
似乎大多数Internet上的网站都使用1460字节作为MTU的值。有时是1452,如果您使用的是VPN,则IPSec标头的丢弃量甚至会更多。
默认窗口大小变化很大,最大为65535字节。我使用http://tcpcheck.com查看自己的源IP值并检查其他Internet供应商正在使用什么。
一种解决方案是将套接字选项TCP_MAXSEG(http://linux.die.net/man/7/tcp)设置为对基础网络“安全”的值(例如,设置为1400以在以太网上安全),然后在发送系统调用中使用较大的缓冲区。这样,可以减少昂贵的系统调用。内核将拆分数据以匹配MSS。
这样,您可以避免数据被截断,并且您的应用程序不必担心小缓冲区。