本文简述下TCP分段和IP分片的区别与联系。
我们知道,用户空间的数据拷贝到内核空间的TCP发送缓冲区(这个是一个结构体,叫sk_buffer,简称skb)后就由内核网络协议栈做后续的封装和发送处理了,用户无需考虑下层的网络问题。
按理来说,MAC帧中搭载的数据部分越长,则一次可发送的数据越多,即数据发送效率就越大。但是由于数据链路的负载能力不是没有上限的,而且为了更方便差错控制,每一种数据链路层协议都规定了数据帧的数据部分上线,即最大传送单元MTU,MAC协议的MTU是1500字节。
这个1500字节不包括以太网的帧头、帧尾,而是包括IP头、TCP头和数据部分。
因此,IP层如果封装后的报文大于1500字节,那就违反了MAC协议,因此无法被封装成MAC帧,IP层此时必须将数据进行分片。
而这1500字节里,还有固定的IP报头20字节,TCP报头的20~60字节(一般是20字节),因此从TCP发送缓冲区到封装成TCP报文,TCP层也需要对数据进行分段,使其起码要小于1460.当然具体来说是小于(MTU - IP头长度 - TCP头度),这个长度成为最大报文长度MSS,英文全称Maximum Segment Size。
这个过程如下图:
问题一:为什么IP对数据分片了,还要TCP分段?
既然IP层会迫于MTU的限制而对数据报进行分片,使其符合MAC协议,并能够正常在以太网中传输。IP层使得数据报满足了MTU,那里面负载的数据肯定小于MSS呀,为什么还需要TCP分段呢?
因为对于一份很大的数据,如果只是IP分片,那么某个数据片丢失后,TCP的重传机制是对这整个数据进行重传,IP是它的下层协议,它不知道IP对这个数据分了多少片,自然也不知道是哪个片丢失了。
而TCP也分段之后,该段数据丢失了,那么TCP只需要重传这一段就可以了。
问题二:TCP有分段,IP还要分片吗?
既然TCP的分段使得数据满足了MSS的要求,肯定也就满足了MTU的要求吧,为什么IP层还是需要对数据分片。
IP分段取决于MTU大小,这个是和网络负载能力有关的。实际上,不同链路负载能力不同,不是所有链路大小都是1500字节。比如IP数据报在到达某路由器时,接下来要走的链路的MTU更小,那么路由器会在IP层对其继续分片,使其满足后面的链路的MTU要求。