文章目录
- IP协议
-
- [1. 前提认识](#1. 前提认识)
-
- [(1) IP的定位和作用](#(1) IP的定位和作用)
- [(2) IP地址的构成](#(2) IP地址的构成)
- [(3) 基本概念](#(3) 基本概念)
- [2. 协议头格式](#2. 协议头格式)
-
- [(1) 两个核心问题](#(1) 两个核心问题)
- [3. 网段划分(重要)](#3. 网段划分(重要))
-
- [(1) 为什么要网段划分](#(1) 为什么要网段划分)
- [(2) 概念](#(2) 概念)
- [(3) 子网划分方案](#(3) 子网划分方案)
- [(4) 模拟子网划分](#(4) 模拟子网划分)
- [4. 特殊的IP地址](#4. 特殊的IP地址)
- [5. IP地址的数量限制](#5. IP地址的数量限制)
- [6. 私有IP地址和公网IP地址](#6. 私有IP地址和公网IP地址)
- [7. 路由及路由表](#7. 路由及路由表)
-
- [(0) 感性理解](#(0) 感性理解)
- [(1) 路由](#(1) 路由)
- [(2) 路由表](#(2) 路由表)
- [8. IP报文的分片与组装](#8. IP报文的分片与组装)
-
- [(1) 为什么](#(1) 为什么)
- [(2) 原理解析](#(2) 原理解析)
- [(3) 得出结论](#(3) 得出结论)
- [(4) 尝试自己分片](#(4) 尝试自己分片)
- [(4) 尝试自己分片](#(4) 尝试自己分片)
IP协议
1. 前提认识
(1) IP的定位和作用
学习TCP协议时一直说是TCP把自己发送缓冲区的数据发送到对方的接收缓冲区,TCP协议所谓的"发送",是什么意思?TCP是真的发送了吗?
一个报文真正被推送到网络且能被网络设备识别的要么是MAC帧,要么是IP报文和它的有效载荷。网络的其他设备一般不关心TCP的报头,只有收发双端会关心。
所以TCP协议并没有真正发送,它所谓的"发送"就是把数据向下交付,交给IP层来处理。
我们所谓的IP, 即IP地址,IP能干什么呢?
我们现在来举一个例子:
- 在班级里有一名叫做张三的同学,他很优秀学习很好,我感觉他考试每次考试都有考100分的能力。那么请问他每次考试是100%能考100分吗?不是,可能有10次考试有7,8次他考100,剩下几次他考98, 99。所以这里的能力指的是:有较大的概率。在IP协议 这里,它提供一种能力(有较大概率),把数据从A主机跨网络送到B主机的能力
- 现在想让张三每次考试都是100%的满分,怎么办呢?张三除了自身优秀,他本人还有一位校长父亲,于是每次学校组织考试,张三考完后不是满分,他父亲就会给张三重新安排考试直至张三考到满分为止。这个场景中张三和校长父亲分别扮演了2种角色:
- 校长父亲:考试控制,为张三考试提供策略
- 张三:执行的,参与每次考试
- 以此类比,用户要的是100%,你怎么保证IP报文100%被对方收到呢?所以我们有TCP/IP协议,校长父亲代表TCP协议,给报文传输提供策略;张三代表IP协议,提供把数据从A主机跨网络送到B主机的能力。两者结合,TCP/IP协议就能将数据从A主机可靠的跨网络送到B主机
- TCP协议:对应端口号(port),IP协议:对应ip地址
- ip:把数据从A送到B(解决了主机通信的问题)
- port:把数据从一个进程送到另一个进程
ip + port :把数据从A主机上的进程跨网络送到B主机上的进程
(2) IP地址的构成
假设我们现在去旅游,要去的目的地是北京的天安门广场。我们肯定是分2步到达:
- 先到景点所在的城市
- 然后到达景点
IP地址也是这样的,IP地址 = 目标网络 + 目标主机。
(3) 基本概念
主机: 配有IP地址的设备; 路由器: 即配有IP地址, 又能进行路由控制; 节点: 主机和路由器的统称;
2. 协议头格式
-
4位版本号(version):指定IP协议的版本, 对于IPv4来说, 就是4(即4字节32bit);IPv4与IPv6并不兼容,IPv6是用128bit来表示IP地址
-
4位头部长度(header length):基本单位是4字节,表示IP头部的长度是多少个32bit, 也就是 length * 4 的字节数。4bit表示最大的数字是15, 因此IP头部最大长度是60字节。
-
8位服务类型(Type Of Service): 3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0)。4位TOS分别表示:最小延时, 最大吞吐量, 最高可靠性, 最小成本。这四者相互冲突, 只能选择一个。对于ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要。
-
16位总长度(total length):IP数据报整体占多少个字节。
-
16位标识(id):唯一的标识主机发送的报文。如果IP报文在数据链路层被分片了, 那么每一个片里面的这个id都是相同的。
-
3位标志字段:第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到)。第二位置为1表示禁止分片, 这时候如果报文长度超过MTU, IP模块就会丢弃报文。第三位表示"更多分片", 如果分片了的话, 最后一个分片置为0, 其他是1。类似于一个结束标记。
-
13位分片偏移(framegament offset):是分片相对于原始IP报文开始处的偏移。其实就是在表示当前分片在原报文中处在哪个位置。实际偏移的字节数是这个值 * 8 得到的。因此, 除了最后一个报文之外, 其他报文的长度必须是8的整数倍(否则报文就不连续了)。
-
8位生存时间(Time To Live, TTL):该报文转发过程中最多经历路由器的次数(即数据报到达目的地的最大报文跳数)。一般是64。每次经过一个路由,
TTL-= 1
, 一直减到0还没到达, 那么就丢弃了。这个字段主要是用来防止出现路由循环 -
8位协议:表示上层协议的类型,即有效载荷是什么报文
-
16位首部校验和:使用CRC进行校验, 来鉴别头部是否损坏。
-
32位源地址和32位目标地址:表示发送端和接收端。(这就是为什么在套接字部分我们把点分10进制字符串风格ip地址转化成4字节ip地址,由于协议需要)
-
选项字段(不定长, 最多40字节):略
(1) 两个核心问题
- 报头和有效载荷如何分离(解包)
- 提取报文的前20字节和4位首部长度
- 4位首部长度 * 4 - 20 == 0
- 等于0(标准报头),报头读取完毕了;
- 不等于0(非标准报头),计算结果就代表有几个字节的选项,继续读取选项即可。
- 读取完报头后,剩下的就是有效载荷,有效载荷就是TCP数据段,有效载荷长度 = 16位总长度 - 4位首部长度
- 有效载荷是如何做到交付给上层的哪一个协议呢?
根据8位协议,表示自己有效载荷是什么报文来向上交付
3. 网段划分(重要)
(1) 为什么要网段划分
现在我们假设一种场景:故事发生在学校。
前提:学校会为每个学生编号,由学校管理者顶层设计出来的学号是有规律的,用来定位学生的唯一性。
我叫张三,今天突然在操场上捡到一个钱包,包里有32块钱和银行卡若干,由于前几天下雨的原因,钱包中学生卡上的姓名等信息已经模糊了,只留下一串学号。我要把钱包还给失主,于是我在学校每碰到一个人就让他给我背学号与学生卡上的学号对比看看是否相等,这样查找的方式可能失主本人已经毕业了我还没找到。用背学号的方式 ,是遍历我们学校所有的学生,时间复杂度:O(n),每次查找排除一次只能排除一人,效率低下。
下面我们以学院为单位,不考虑专业和班级。我想到学校还有学生会,每个学院都有自己的群,群主是院学生会主席,又给院学生学生会主席拉群形成学生会主席群,同时每个学院都有自己的编号,一个学生的学号是由:院号 + 院内序号 构成的。 我的学号是:10299,钱包中学号是:15003,虽然我不知道她是谁,但我知道她不是我们学院的学生。我把钱包中学号信息拍照放到计算机学院的群里。此时院学生会主席虽然不知道15003是哪个学生,但是他知道这名学生隶属于电工院的,他直接把消息转到学生会主席群并@电工院主席,电工院主席看到学院编号是15,确定是自己院的,于是把消息转到电工院群里@003号同学,让他确认钱包是自己的后联系张三,003同学看到后联系张三拿回自己的钱包。
-
上面以学生会的方式归还钱包的效率明显提高,为什么?不是以个人为查找单位的,是以群为单位。查找的本质是排除的过程,选择一个群,就是排除了其他所有的群,查找效率大大提高。
-
这里的群:称为子网;院学生会主席:路由器;学生会主席群:转发集群,公网;群里的各个人:主机;学号:IP地址
-
查找钱包的过程:
-
先找到到目标群(子网)
-
再找到目标人(目标主机)
-
-
为什么要拉群:提高查找效率
-
为了能够让我们将数据从A跨网络更高效地送到B,所以我们必须进行子网划分。
-
IP地址 = 目标网络 + 目标主机。IP地址的构成是子网划分的结果,提高全球中任何一台主机查找另一台主机的效率
那我们现在就有疑问了,子网划分是谁做的
运营商,国内的网络一定是被国内的运营商顶层设计过的!国际,大家商量着来。
(2) 概念
IP地址分为两个部分, 网络号和主机号
- 网络号:保证相互连接的两个网段具有不同的标识;
- 主机号:同一网段内, 主机之间具有相同的网络号, 但是必须有不同的主机号;
- 不同的子网其实就是把网络号相同的主机放到一起。
- 如果在子网中新增一台主机, 则这台主机的网络号和这个子网的网络号一致, 但是主机号必须不能和子网中的其他主机重复。
通过合理设置主机号和网络号, 就可以保证在相互连接的网络中, 每台主机的IP地址都不相同。
那么问题来了, 手动管理子网内的IP, 是一个相当麻烦的事情。
- 有一种技术叫做DHCP, 能够自动的给子网内新增主机节点分配IP地址, 避免了手动管理IP的不便。
- 一般的路由器都带有DHCP功能。因此路由器也可以看做一个DHCP服务器
补充:
-
上图路由器级联了2个子网,必须配2个IP地址。
-
路由器代表子网的出口或入口,一般都是整个子网的1号主机。当你进行入网时,路由器一定是子网中的第一个设备。(就像家里的无线路由器)
- 路由器可以构建子网。我用手机开热点,我和使用热点的人构成一个子网,我的手机就相当于路由器。
- 子网的构建是路由器帮我们构建好的,所以局域网内所有主机的IP地址都是从路由器里申请的;你在上网时要先连wifi,连wifi本质就是向路由器动态申请IP地址。
(3) 子网划分方案
过去曾经提出一种划分网络号和主机号的方案, 把所有IP 地址分为五类, 如下图所示
- A类 0.0.0.0到127.255.255.255
- B类 128.0.0.0到191.255.255.255
- C类 192.0.0.0到223.255.255.255
- D类 224.0.0.0到239.255.255.255
- E类 240.0.0.0到247.255.255.255
随着Internet的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请B类网络地址, 导致B类地址很快就分配完了, 而A类却浪费了大量地址;
- 例如, 申请了一个B类地址, 理论上一个子网内能允许6万5千多个主机。A类地址的子网内的主机数更多。
- 然而实际网络架设中, 不会存在一个子网内有这么多的情况。因此大量的IP地址都被浪费掉了。
针对这种情况提出了新的划分方案, 称为CIDR(Classless Interdomain Routing):
- 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号;
- 子网掩码也是一个32位的正整数. 通常用一串 "0" 来结尾;
- 将IP地址和子网掩码进行 "按位与" 操作, 得到的结果就是网络号;
- 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关;
示例1:
IP地址中的主机地址全部设为0, 代表网络号;将IP地址中的主机地址全部设为1, 代表广播地址。所以不用全0和全1表示的主机号,即0~255一共256个IP地址,接入的主机数一共256-2=254个
示例2:
(4) 模拟子网划分
说明:下面子网划分的过程是以国家,省,市为单位的,实际子网划分并非如此而是以地区,人口密度等划分的
一位美国人IP地址1.2.3.4想要访问2.4.4.23的网站,国内出口路由器发现不是本国内的,于是转发到公网上,公网路由器识别出哪个国家后转发到本国的入口路由器处,后将2.4.4.23与子网掩码按位与得到网络号,由本国内的路由器识别后继续向下转发最后访问到了西安某地区的网站。
上面我们是以公网的形式划分子网,并未画全同时发现划分到某市的某个区再往下去细分,这种方式很快把IP地址分配完了。所以实际中并不是这样的,到了一定区域内会构建局域网使用私有IP(后面讲)
4. 特殊的IP地址
- 将IP地址中的主机地址全部设为0, 就成为了网络号, 代表这个局域网;
- 将IP地址中的主机地址全部设为1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数据包;
127.*
的IP地址用于本机环回(loop back)测试,通常是127.0.0.1
5. IP地址的数量限制
我们知道, IP地址(IPv4)是一个4字节32位的正整数。那么一共只有2的32次方个IP地址, 大概是43亿左右。而TCP/IP协议规定, 每个主机都需要有一个IP地址。
这意味着, 一共只有43亿台主机能接入网络么?
实际上, 由于一些特殊的IP地址的存在, 数量远不足43亿; 另外IP地址并非是按照主机台数来配置的, 而是每一个网卡都需要配置一个或多个IP地址。
CIDR在一定程度上缓解了IP地址不够用的问题(提高了利用率, 减少了浪费, 但是IP地址的绝对上限并没有增加), 仍然不是很够用。 这时候有三种方式来解决:
- 动态分配IP地址: 只给接入网络的设备分配IP地址。因此同一个MAC地址的设备, 每次接入互联网中, 得到的IP地址不一定是相同的;
- NAT技术(后面会重点介绍);
- IPv6: IPv6并不是IPv4的简单升级版。 这是互不相干的两个协议, 彼此并不兼容; IPv6用16字节128位来表示一个IP地址; 但是目前IPv6还没有普及;
6. 私有IP地址和公网IP地址
如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,理论上 使用任意的IP地址都可以,但是RFC 1918规定了用于组建局域网的私有IP地址。
10.*
, 前8位是网络号,共16,777,216个地址172.16.
到172.31.
,前12位是网络号,共1,048,576个地址192.168.
,前16位是网络号,共65,536个地址
包含在这个范围中的, 都成为私有IP, 其余的则称为全局IP(或公网IP);
- 一个路由器可以配置两个IP地址, 一个是WAN口IP, 一个是LAN口IP(子网IP)。
- 路由器LAN口连接的主机, 都从属于当前这个路由器的子网中。
- 不同的路由器, 子网IP其实都是一样的(通常都是192.168.1.1)。子网内的主机IP地址不能重复。但是子网之间的IP地址就可以重复了。
- 每一个家用路由器, 其实又作为运营商路由器的子网中的一个节点。这样的运营商路由器可能会有很多级,最外层的运营商路由器, WAN口IP就是一个公网IP了。
- 子网内的主机需要和外网进行通信时, 路由器将IP首部中的IP地址进行替换(替换成WAN口IP), 这样逐级替换, 最终数据包中的IP地址成为一个公网IP。这种技术称为NAT (Network Address Translation,网络地址转换)。
- 如果希望我们自己实现的服务器程序,能够在公网上被访问到, 就需要把程序部署在一台具有外网IP的服务器上。这样的服务器可以在阿里云/腾讯云上进行购买。
源IP在内网中不断被替换的过程称为NAT技术,由此我们可以在LAN口IP处配置IPV6,WAN口IP处配置IPV4,很容易做到在内网环境中使用IPV6。
大家也可以ifconfig
查看自己的云服务器IP
7. 路由及路由表
(0) 感性理解
时间线拉回20年前,我考上了上海的同济大学。现在开学了,我要坐火车去上学,刚下火车发现自己的行李不见了,也没有手机,只有兜里的20块钱,想着到了大学就能寻求辅导员的帮助,但是此时我并不知道同济大学在哪里。于是我出了火车站开始找人问路,在路边看见了一个大爷询问怎么去同济大学,他告诉我沿着这条路走200米到公交站坐308公交车一下车能到上海的东北角(假设同济大学就在上海的东北角);我下公交车又不知道咋走了于是又找了一个大爷问路,大爷让我去找左手边50米处的大妈寻求帮助,大妈在这里扫地20年了,她对周围方圆50里很熟悉;大妈告诉我下一站去哪,我坐上公交车去,下了车又不认识路了,看到门口的大爷后找他问路,他缓缓地走回门房掏出一块牌子上面写着:同济大学,告诉我他是同济大学的保安,我已经到了。
上面的故事里:
- 我问路时一定要告诉别人我要去哪里,就像报文到了某个路由器内部一定会在报头中携带目的IP告诉路由器去哪里,此目的IP地址就如同同济大学
- 当我问大爷路时,大爷在思考,思考的过程是拿着我的目的地址在自己大脑里做筛选对比,无论是否找到都会给我结果,大爷和大妈所作的工作就是查找路由表
- 即使大爷不知道我该怎么走,还是会让我去寻找大妈的帮助。路由器不知道报文去哪里,但是确定不在现在的网络里,把报文推向了默认路由,大妈就是默认路由
- 我把自己路由到同济大学的保安大爷时,他告诉我已经到同济大学了。这叫做报文到达了目标子网的入口路由器处
- 我其实并不是要去同济大学,而是要去同济大学的18号宿舍楼找辅导员,当我在路上时我只会问同济大学在哪,到了同济大学后我会问18号宿舍楼在哪里;在路上我根据目标网络查找,当到了入口路由器处我根据目标主机查找交付
- 上面的过程就是路由转发,会涉及到目的IP查路由表的过程。
(1) 路由
路由的过程, 就是这样一跳一跳(Hop by Hop) "问路" 的过程。
所谓 "一跳" 就是数据链路层中的一个区间。具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间。
IP数据包的传输过程也和问路一样。
- 当IP数据包, 到达路由器时, 路由器会先查看目的IP;
- 路由器决定这个数据包是能直接发送给目标主机, 还是需要发送给下一个路由器;
- 依次反复, 一直到达目标IP地址;
那么如何判定当前这个数据包该发送到哪里呢? 这个就依靠每个节点内部维护一个路由表;
(2) 路由表
- 路由表可以使用route命令查看
- 如果目的IP命中了路由表, 就直接转发即可;
- 路由表中的最后一行,主要由下一跳地址和发送接口两部分组成,当目的地址与路由表中其它行都不匹配时,就按缺省路由条目规定的接口发送到下一跳地址。
假设某主机上的网络接口配置和路由表如下:
-
这台主机有两个网络接口,一个网络接口连到192.168.10.0/24网络,另一个网络接口连到192.168.56.0/24网络;
-
路由表的Destination是目的网络地址 , Genmask是子网掩码 , Gateway是下一跳地址,Iface是发送接口,Flags中的U标志表示此条目有效(可以禁用某些条目), G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发;
转发过程例1: 如果要发送的数据包的目的地址是192.168.56.3
- 跟第一行的子网掩码做与运算得 到192.168.56.0,与第一行的目的网络地址不符
- 再跟第二行的子网掩码做与运算得 到192.168.56.0,正是第二行的目的网络地址,因此从eth1接口发送出去;
- 由于192.168.56.0/24正 是与eth1 接口直接相连的网络,因此可以直接发到目的主机,不需要经路由器转发;
转发过程例2: 如果要发送的数据包的目的地址是202.10.1.2
-
依次和路由表前几项进行对比, 发现都不匹配;
-
按缺省路由条目, 从eth0接口发出去, 发往192.168.10.1路由器;
-
由192.168.10.1路由器根据它的路由表决定下一跳地址;
8. IP报文的分片与组装
(1) 为什么
最大传输单元(MTU)
数据链路层的MAC帧协议规定了自己的有效载荷不能超过超过某个值,这个值就叫做最大传输单元(Maximum Transmission Unit,MTU),这个值的大小一般是1500字节。这1500个字节限制包括了IP报头+IP报文中的有效载荷。所以一旦IP发送数据超过1500字节时,就需要先在IP层对该数据进行分片,然后再将分片后的数据交给下层
在Linux下使用ifconfig
命令可以查看对应的MTU。
(2) 原理解析
-
16位标识(id):唯一的标识主机发送的报文。如果IP报文在数据链路层被分片了, 那么每一个片里面的这个id都是相同的。
-
3位标志:第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到)。第二位置为1表示禁止分片,这时候如果报文长度超过MTU, IP模块就会丢弃报文。第三位表示"更多分片", 如果分片了的话, 最后一个分片置为0, 其他是1。类似于一个结束标记。
-
13位分片偏移(framegament offset):是分片相对于原始IP报文开始处的偏移。其实就是在表示当前分片在原报文中处在哪个位置。实际偏移的字节数是这个值 * 8 得到的。因此, 除了最后一个报文之外, 其他报文的长度必须是8的整数倍(否则报文就不连续了)。
怎么做的分片和组装呢?根据上面3个报头字段,以一个长度为4500的报文为例
上面就是分片的过程,组装时只需将报文按照13位片偏移升序排序后线性遍历即可。
原理解析
-
同一时间段内,接收方可能收到了大量的IP报文分片,它怎么分辨这些报文分片属于哪个客户端呢?
接收方收到的IP报文中,IP报头中携带了32位源IP地址,根据源IP地址就具有了区分不同客户端的能力
-
你怎么知道分片了呢?
- 片偏移!=0或更多分片==1
- 片偏移是0,更多分片是1
报文类型 | 更多分片 | 片偏移 |
---|---|---|
开始报文 | 1 | 0 |
中间报文 | 1 | 大于0 |
结束报文 | 0 | 大于0 |
独立报文 | 0 | 0 |
-
怎么保证你把分片全收到了呢
- 头尾报文一旦丢失,我们根据片偏移和更多分片可以知道
- 中间报文一旦丢失,我们可以按照偏移量进行排序
-
怎么保证把分片组装在一起呢?
按照13位片偏移量对报文进行排序
-
怎么保证组合在一起的分片一定是对的?
-
首部:IP报头中存在16位首部校验和,一旦IP报头出现问题会将此报文丢弃;
-
内容:TCP报头中存在16位校验和,一旦检测TCP自己的报文(即IP的有效载荷)内容有问题会将此报文丢弃
-
(3) 得出结论
在网络中,分片尽量让它成为少数情况
为什么要避免分片?
即使传输层并不关心IP层的分片问题,但是分片也会对传输层产生影响。
- 在没有分片时,只要接收端收到一个报文并给发送端ACK应答了,我们就认为这个数据被对方可靠收到了
- 但是对报文分片后,发送给接收端众多的分片报文中一旦有一个报文丢包,导致接收端无法将这些报文组装起来,会直接丢弃整个报文,此时TCP层没有收到应答,会对接收端进行超时重传。因此分片会增加传输层重传数据的概率。
- 假设在网络传输时丢包的概率是1%,如果将报文分片后进行发送,那么此时任意一个报文丢包的概率就大大提升,因为只要有一个分片报文丢包了就等同于整个报文整体丢失了。即过多的分片容易增加丢包率
怎么做才能避免分片?
让传输层向下交付的数据尽量不要过大
TCP作为传输控制协议,它需要控制一次向下交付数据不能超过某一阈值,这个阈值就叫做MSS(Maximum Segment Size,最大报文段长度)。这就是为什么TCP滑动窗口中,为什么不把滑动窗口里面的范围报文之间到一个包整体发出,而要分成多个报文发出的原因。
MAC帧的有效载荷最大为MTU,MTU的大小一般是1500字节。IP标准报头20字节,则IP有效载荷=1500 - 20 = 1480。IP有效载荷=TCP报文,TCP标准报头20字节,TCP有效载荷 = 1480 - 20 =1460。因此MSS的值一般就是1460字节。
(4) 尝试自己分片
分片后,每一片都是IP报文,要给没有报头的IP报文添加报头。
超时重传。因此分片会增加传输层重传数据的概率。
- 假设在网络传输时丢包的概率是1%,如果将报文分片后进行发送,那么此时任意一个报文丢包的概率就大大提升,因为只要有一个分片报文丢包了就等同于整个报文整体丢失了。即过多的分片容易增加丢包率
怎么做才能避免分片?
让传输层向下交付的数据尽量不要过大
TCP作为传输控制协议,它需要控制一次向下交付数据不能超过某一阈值,这个阈值就叫做MSS(Maximum Segment Size,最大报文段长度)。这就是为什么TCP滑动窗口中,为什么不把滑动窗口里面的范围报文之间到一个包整体发出,而要分成多个报文发出的原因。
MAC帧的有效载荷最大为MTU,MTU的大小一般是1500字节。IP标准报头20字节,则IP有效载荷=1500 - 20 = 1480。IP有效载荷=TCP报文,TCP标准报头20字节,TCP有效载荷 = 1480 - 20 =1460。因此MSS的值一般就是1460字节。
(4) 尝试自己分片
分片后,每一片都是IP报文,要给没有报头的IP报文添加报头。