zoukankan      html  css  js  c++  java
  • TCP和IP什么情况分包

    概述

    我们知道知道数据经过层层封装后最后通过数据链路层发往另外一个终端 , 那么当发往的数据的大小太大了,TCP/IP 就会通过分包(一个变多个),然后再传到链路层进行发送 . 我们先来看一下网络分层

    1297993-20210603114724241-1967695471.jpg

    1297993-20210603114737761-1669325959.png

    1297993-20210603114752660-1139807112.png

    MTU

    MTU 最大传输单元(Maximum Transmission Unit,MTU)用来通知对方所能接受数据服务单元的最大尺寸,说明发送方能够接受的有效载荷大小。在不同的协议中 MTU 的值是不同的 , 例如 :

    1297993-20210614221201655-524755509.png

    如果IP层有一个数据报要传,而且数据帧的长度比链路层的MTU还大,那么IP层就需要进行分片( fragmentation),即把数据报分成干片,这样每一片就都小于MTU . 为了解释 MTU 的概念可以看下面的例子 ,

    MTU 的值不是越大越好,更大的 MTU 意味着更低的额外开销,更小的 MTU 意味着更低的网络延迟。每一个物理设备都有自己的 MTU,两个主机之间的 MTU 依赖于底层的网络能力,它由整个链路上 MTU 最小的物理设备决定3,如下图所示,网络路径的 MTU 由 MTU 最小的红色物理设备决定,即 1000:
    

    1297993-20210614221605731-265975676.png

    图片来源 : https://draveness.me/whys-the-design-tcp-segment-ip-packet/
    

    两台主机通信路径中的最小MTU,称为路径MTU( Path mtu,PMTU),也就是上面的这个 1000 个字节为该连接的 PMTU 你也看到了以太网MTU一般为 1500 个字节, 也就是说超过 1500 个字节的数据就会分包发送,那么我们反推一下 ,

    IP 整体大小 = IP Header + TCP = 20 + 1480 = 1500 
    TCP 整体大小 = TCP Header + TCP Playload = 20 + 1460 = 1480 
    
    

    也就是说我只要在TCP 三次握手MSS 协商的时候传输的数据小于 1480 不就行了吗? MSS 能完全避免 IP 分片吗,肯定不行, MTU 有可能会变呀 ,而且由于网络异常等原因或是物理设备等原因 .

    IP 中的 MTU 是物理设备上的限制,它限制了路径能够发送数据包的上限,那么如何知道某一个链路中的 MTU , 下面我们将介绍 路径最大传输单元发现(Path MTU Discovery,PMTUD)

    看一个例子

        例子来源 : https://zhuanlan.zhihu.com/p/139537936
    

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

    一旦DF位置一,(DF位为1的话则不允许分片)将不允许中间设备对该报文进行分片,那么在遇到IP报文长度超过中间设备转发接口的MTU值时,该IP报文将会被中间设备丢弃。在丢弃之后,中间设备会向发送方发送ICMP差错报文(告诉发送者,你发送的数据大小超过了我的MTU , 需要发小点体积的数据).这个过程如下 :

    1297993-20210614222953924-1597264926.jpg

    通过抓包

    1297993-20210614223036636-2047307795.jpg

    我们可以看到其差错类型为3,代码为4,并且告知了下一跳的MTU值为1478。在ICMP差错报文里封装导致此差错的原始IP报文的报头(包含IP报头和四层报头)。

    一旦出现这种因DF位置一而引起丢包,如果客户端无法正常处理的话,将会导致业务应用出现异常,外在表现为页面无法打开、页面打开不全、某些大文件无法传输等等,这将严重影响业务的正常运行。 那么客户端如何处理这种状况呢? TCP主要通过两种方式来应对:

    1. 协商MSS,在交互之前避免分片的产生
    2. 路径MTU发现(PMTUD)

    PMTUD

        这里引用来自 : https://draveness.me/whys-the-design-tcp-segment-ip-packet/ 的例子 ,非原创 
    

    步骤一 : 向目的主机发送 IP 头中 DF 控制位为 1 的数据包,DF 是不分片(Don’t Fragment,DF)的缩写;路径上的网络设备根据数据包的大小和自己的 MTU 做出不同的决定: (1) 如果数据包大于设备的 MTU,就会丢弃数据包并发回一个包含该设备 MTU 的 ICMP 消息;顺便带回去建议的MTU 大小 (2) 如果数据包小于设备的 MTU,就会继续向目的主机传递数据包;

    步骤二 : 源主机收到 ICMP 消息后,会不断使用新的 MTU (根据带回来别人建议的 MTU 大小)发送 IP 数据包,直到 IP 数据包达到目的主机;

    MSS 协商

    1297993-20210614223334719-773129879.jpg

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

    需要注意的知识点

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

    总结

    TCP/IP 的 PMTU 的发现机制尽可能地为了减少分片的可能 , 我们在优化的时候要将这个原则考虑进去 .

    参考资料

    • https://mp.weixin.qq.com/s/RP6w69I-q5ai9Bx_SzjUfQ
    • https://draveness.me/whys-the-design-tcp-three-way-handshake/
    • https://zhuanlan.zhihu.com/p/139537936
  • 相关阅读:
    Javascript闭包的一些研究
    pytorchvision安装问题
    CUDA 基础
    语音识别入门推荐文献【转】
    【e2e】espnet框架安装问题集锦
    维特比算法与beam search
    kaldi识别问题集锦
    语音识别-重要开源数据
    git提交失败总结
    钟南山病后反思: 寿命长短, 不取决于衰老和疾病【转】
  • 原文地址:https://www.cnblogs.com/Benjious/p/14883699.html
Copyright © 2011-2022 走看看