TCP避免分片

转自:http://blog.chinaunix.net/uid-27164517-id-3360202.html


    我们知道,当应用层程序之间进行网络数据传输时,在发送端,数据会从应用层沿着协议栈向下传输,通过TCP/IP层,然后经由链路层发送出去,而在接收端,则是相反的顺序,数据经由链路层接收,然后沿着协议栈向上传输,通过IP/TCP层,最后由应用层程序进行读取。

 


 

而在IP层往链路层传输数据的时候,往往会做一个分片的操作,对于大多数链路层来讲,它都有一个最大传输单元(MTU),表示能够发送数据量的大小,它是由硬件决定的。比如以太网的MTU为1500字节。当IP层传输给链路层的数据量大于其MTU时,那么IP层就会将数据拆分为小于其链路层MTU的数据片,再传输给链路层进行发送。

 


但是对于不同的传输层协议(TCP/UDP)来说,在IP层上,需不需要进行分片是不同的。

 

TCP层的分片

 

对于TCP来说,它是尽量避免分片的,为什么?因为如果在IP层进行分片了话,如果其中的某片的数据丢失了,对于保证可靠性的TCP协议来说,会增大重传数据包的机率,而且只能重传整个TCP分组(进行IP分片前的数据包),因为TCP层是不知道IP层进行分片的细节的,也不关心。

 

当TCP层进行TCP分组的重传后,还会直接影响到应用层程序的性能,特别是在应用程序使用阻塞IO进行读写的时候。要理解这点,首先我们要知道当应用层程序往TCPIP协议栈写数据的时候都做了些什么事。

 

在应用层程序中,我们可以有自己的发送缓冲区,而TCP层本身也有自己的一个发送缓冲区,在JAVA中,可以通过设置Socket的SO_SNDBUF选项来设置,默认情况下一般是8k大小。 当我们在应用层往TCP层写数据(比如outputstream.write())的时候,实际上是将应用层发送缓冲区的数据拷贝到TCP层的发送缓冲区中。当TCP层的发送缓冲区满或者网络空闲时,TCP层就会将其缓冲区中的数据通过IP层传到链路层的发送队列中。如果TCP层的发送缓冲区满而且应用层的数据没有写完时,内核会将write系统调用挂起,并不返回给应用层程序,直到应用层的数据全部拷贝到TCP层的缓冲区中。而由于TCP层要保证数据包的可靠性,即数据包丢失时要进行重传,那么TCP层在往网络发送TCP分组后,需要在其发送缓冲区中暂时保存发出的TCP分组数据用于后续可能的重传。

 


 

在这样的前提下,如果IP对来自TCP层的数据进行了分片, 那么就有可能使得应用层程序一直在write系统调用处挂起等待,引起性能的下降。

 

 

TCP层如何避免IP层的分片

首先,我们先回顾下TCP建立连接的3次握手:

 


在这3次握手中,除了确认SYN分节外,通信的两端还进行协商了一个值,MSS,这个值用来告诉对方,能够发送的TCP分节的大小。这个值一般是取其链路层的MTU大小减去TCP头部大小和IP头部的大小。MSS=MTU-TCP头部大小-IP头部大小. MTU的值可以通过询问链路层得知。

 

当两端确认好MSS后进行通信,当TCP层往IP层传输数据时,如果TCP层缓冲区的大小大于MSS,那么TCP层都会将其发送缓冲区中的数据切分成MSS大小的分组进行传输,由于MSS是通过MTU减去TCP头部大小和IP头部的大小计算得出的,MSS肯定比MTU小,那么到IP层的时候就可以避免IP层的分片。

 

 

 

UDP层的分片

如果我们采用的是UDP协议而不是TCP协议呢?在IP层会不会进行分片?由于UDP是不需要保证可靠性的,那么它就不会保存发送的数据包,TCP之所以保存发送的数据包是因为要进行重传。所以UDP本身是没有像TCP一样的发送缓冲区的。这就导致了对UDP进行write系统调用的时候,实际上应用层的数据是直接传输到IP层,由于IP层本身也不会有缓冲区,数据就会直接写到链路层的输出队列中。

 

在这种情况下,IP层会不会对来自UDP的数据进行分片呢?这个取决于UDP数据报的大小。如果UDP数据报的大小大于链路层的MTU,那么IP层就会直接进行分片,然后在发送到链路层的输出队列中,反之,则不会进行分片,直接加上IP头部发送到链路层的输出队列中。

<think>首先,用户的问题是:“TCP协议在FTP文件传输中如何避免或减少分片?” 这是基于我之前的回答中提出的相关问题的第二个问题。 我需要用中文回答问题。用户指定了:“请使用中文回答问题”,所以我的整个响应必须用中文。 我的回答结构: 1. 先回答问题:解释TCP协议在FTP文件传输中如何避免或减少分片。 2. 然后,在回答末尾,提出3-5个相关问题。 3. 相关问题必须以“§§相关问题§§”开头,并且这是第一行,必须完整输出。 4. 禁止换行分散,意思是相关问题应该连续列出,要有额外的换行。 从示例格式看: - 回答完问题后,直接输出“§§相关问题§§” - 然后列出问题,用数字点号,如“1. ···”,每个问题一行,但要换行分散,意思是保持紧凑,可能每个问题占一行。 在示例中,它是: ``` §§相关问题§§ 1. ··· 2. ··· 3. ··· ``` 所以,我应该模仿这个格式。 现在,针对问题:“TCP协议在FTP文件传输中如何避免或减少分片?” 从之前的上下文,我知道: - FTP使用TCP进行数据传输。 - TCP负责将数据流分割成段(segments)。 - 分片发生在IP层,当数据大小超过MTU时。 - TCP可以通过MSS(Maximum Segment Size)来避免或减少分片。 关键点: - TCP在建立连接时,通过三次握手协商MSS(最大段大小)。 - MSS是基于MTU设置的,通常小于MTU以避免IP分片。 - 例如,在以太网上,MTU是1500字节,TCP/IP头共40字节(20字节IP头 + 20字节TCP头),所以MSS通常为1460字节。 - 这样,TCP段大小会超过MTU,从而避免IP分片。 - 在FTP传输中,TCP处理数据分割,确保每个段大小超过MSS。 - 路径MTU发现(Path MTU Discovery)机制可以动态调整MSS以适应网络路径。 - 因此,TCP通过控制段大小来减少或避免IP分片。 所以,我的回答应该括: - TCP使用MSS来避免分片。 - 协商MSS的过程。 - 路径MTU发现的作用。 - 强调在FTP上下文中,TCP处理数据分割。 用中文表述。 然后,提出3-5个相关问题。相关问题应该基于当前问题和我的回答。 可能的基于当前问题的问题: 1. MSS是什么?它是如何工作的? 2. 路径MTU发现机制是什么? 3. 如果MTU匹配,会发生什么? 4. TCP如何确保数据可靠传输同时避免分片? 5. 在FTP中,还有其他方式优化传输吗? 确保3-5个问题。 最后,输出格式: - 先回答问题。 - 然后“§§相关问题§§” - 然后1. ... 2. ... 等。 在回答中,需要代码块,除非必要。用户的问题是关于概念的,所以我应该用文本解释。 完整响应结构: - 回答部分。 - §§相关问题§§ - 相关问题列表。 用中文写。</think>TCP协议在FTP文件传输中避免或减少分片主要通过以下机制实现: 1. **MSS(Maximum Segment Size)协商**:在TCP三次握手建立连接时,客户端和服务器交换MSS值(通常基于网络接口的MTU减去IP和TCP头大小,例如以太网MTU为1500字节时,MSS默认为1460字节)。这确保TCP段大小超过路径的MTU,从而避免IP层分片。 2. **路径MTU发现(Path MTU Discovery)**:TCP使用ICMP消息探测路径上的最小MTU,并动态调整MSS以适应网络条件。如果探测到较小MTU,TCP会自动减小段大小,防止分片发生。 3. **段大小控制**:TCP在传输层将数据流分割为固定大小的段(超过MSS),FTP应用层仅处理文件数据流,干预分割过程。这减少了IP层处理大的需求。 通过这些机制,TCP在FTP传输中有效减少了IP分片的发生,提高了传输效率和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值