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 共同协商
上面我们已经知道了,
我们可以看到在三次握手的时候就双方就进行过协商,最大程度地减少数据传输到 IP 层然后进行分包的可能.
三次握手中协商了MSS就不会改变了吗?
不是,每次执行TCP发送消息时,会重新计算一次MSS,再进行分段操作。
对端不传MSS会怎么样?
我们再看TCP的报头。
其中 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 限制, 就会带来更多额外的重传和重组开销,影响性能
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了