TCP-MSS

什么是 MSS , MSS 的动机是什么

MSS(Maximum Segment Size,最大报文长度),是TCP协议定义的一个选项,MSS选项用于在TCP连接建立时,收发双方协商通信时每一个报文段所能承载的最大数据长度。

    原文链接:https://blog.csdn.net/meihualing/article/details/113739693

    我们都知道,如果TCP/UDP往IP层发送数据时,因为物理网络层一般要限制每次发送数据帧的最大长度。所以IP层接收到一份要发送的IP数据报时,它要判断向本地哪个接口发送数据(选路),并查询该接口获得其MTU。
    
    IP把MTU与数据报长度进行比较,如果太长了一次发送不下(超过MTU)则需要则进行分片。分片可以发生在原始发送端主机上,也可以发生在中间路由器上。

    UDP无法避免分片(除非应用层知道路径MTU并控制UDP报文大小),TCP则通过MSS协商来避免分片发生。

假设 MTU= 1500 byte,那么 MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte,如果应用层有 2000 byte 发送,那么需要两个切片才可以完成发送,第一个 TCP 切片 = 1460,第二个 TCP 切片 = 540。

MSS 的大小与 MTU 有关, 为:

MTU - (TCP 标头 + IP 标头) = MSS

MSS 共同协商

上面我们已经知道了,

1297993-20210614223334719-773129879.jpg

我们可以看到在三次握手的时候就双方就进行过协商,最大程度地减少数据传输到 IP 层然后进行分包的可能.

三次握手中协商了MSS就不会改变了吗?

不是,每次执行TCP发送消息时,会重新计算一次MSS,再进行分段操作。

对端不传MSS会怎么样?

我们再看TCP的报头。

img

其中 MSS 位于可选项中, 假如对方不传 ,那么 MSS 默认为 : 536 byte , 为什么是这个数字是因为 :

536(data) + 20(tcp头)+20(ip头)= 576Byte

默认 MSS 大小的考虑有两方面 :

  • 太小 , tcp 头有20个字节, ip头也有20个字节, MSS 太小的话 ,利用率会不高
  • 太大 , MSS 太大的话会造成 IP 重传

576字节正好是 IP 最小重组缓冲区的大小, 我们想想要是这个 IP 包发送途中丢失了 , 那么TCP 的重传机制肯定会再次发起重新传输 , 而IP 最小重组缓冲区的大小正好避免了重传 .

为什么IP层会分片,TCP还要分段

这是因为假如 TCP 不分段的话, 需要传输一大份数据的时候 ,有可能数据丢失了, 那么 TCP 就得传输整份完整的数据 ,而分段的话, 丢失了哪一块就传哪一块 ,提高了效率.

TCP分段了,IP层就一定不会分片了吗

上面提到了,在发送端,TCP分段后,IP层就不会再分片了。

但是整个传输链路中,可能还会有其他网络层设备,而这些设备的MTU可能小于发送端的MTU。此时虽然数据包在发送端已经分段过了,但是在IP层就还会再分片一次。
如果链路上还有设备有更小的MTU,那么还会再分片,最后所有的分片都会在接收端处进行组装。

因此,就算TCP分段过后,在链路上的其他节点的IP层也是有可能再分片的,而且哪怕数据被第一次IP分片过了,也是有可能被其他机器的IP层进行二次、三次、四次….分片的。

因此要想整个链路不发生分包, 那么可以使用上一个章节讲到的 PMTU , 这样IP就不会发生分片了.

MTU 和 MSS 的联系

    来自 : https://blog.csdn.net/liangzhiyang/article/details/121774339

(发生在发送端)发送端进行TCP分段后就一定不会在IP层进行分片,因为MSS本身就是基于MTU推导而来,TCP层分段满足了MSS限制,也就满足了MTU的物理限制。但在TCP分段发生后仍然可能发生IP分片(发生在传输过程中),这是因为TCP分段仅满足了通信两端的MTU要求,传输路径上如经过MTU值比该MTU值更小的链路,那么在转发分片到该条链路的设备中仍会以更小的MTU值作为依据再次分片。当然如果两个通信主机直连,那么TCP连接协商得到的MTU值(两者网卡MTU较小值)就是端到端的路径MTU值,故发送端只要做了TCP分段,则在整个通信过程中一定不会发生IP分片。

特别地,对中途发生分片的数据报而言,即使只丢失其中一片数据也要重传整个数据报(这里既然有重传,说明传输层使用的是具有重传功能的协议,如TCP协议。而UDP协议不可靠,即使丢包了也不在意更不会重传,所以必须在应用层实现可靠通信的逻辑),这是因为IP本身没有重传机制,只能由更高层,比如传输层的TCP协议,来负责重传以确保可靠传输。于是,当来自同一个TCP报文段封装得到的原始IP数据报中的的某一片丢失后,接收端TCP迟迟接受不到完整报文段,它就会认为该报文段(包括全部IP分片)已丢失,TCP之后由于超时会收到三个冗余ACK就会重传整个TCP报文段,该报文段对应于一份IP数据报,可能有多个IP分片,但没有办法单独重传其中某一个数据分片,只能重传整个报文段。

经常遇到的 Socket粘包是怎么回事

为什么会黏包, 因为socket 里面的数据是业务数据 ,而传过来的时候有可能是经过分段的到达的, 我们并不知道到哪才截止, 所以有可能导致数据粘包 , 解决的方法也非常简单 , 只要加上一个长度就够了.

总结

  • IP 协议的 MTU 是物理设备上的限制,它限制了路径能够发送数据包的上限,而 TCP 协议的 MSS 是操作系统内核层面的限制,通信双方会在三次握手时确定这次连接的 MSS。一旦确定了 MSS,TCP 协议就会对应用层交给 TCP 协议发送的数据进行拆分,构成多个数据段。IP 的 MTU 大小对上面 TCP 是透明 , 可以让上层协议读取得到的.
  • TCP 协议拆分数据是为了保证传输的可靠性和顺序,作为可靠的传输协议,为了保证数据的传输顺序,它需要为每一个数据段增加包含序列号的 TCP 协议头,如果数据段大小超过了 IP 协议的 MTU 限制, 就会带来更多额外的重传和重组开销,影响性能

参考资料

posted @ 2022-07-03 16:06  float123  阅读(1928)  评论(0编辑  收藏  举报