⽹络层
IP协议
我们TCP报文是封装成IP报文发送下去的。
IP就是具有从主机A跨网络发送到主机B的能力。
IP的构成是 = 目标网络+目标主机的。

主机: 配有IP地址, 也要进⾏路由控制的设备;
路由器: 即配有IP地址, ⼜能进⾏路由控制;
节点: 主机和路由器的统称;
我们向从主机B到达主机C为什么我一定是B->F,F->G...最终到达F,为什么会这样呢?
因为我要去主机C,所以我得是B->F,F->G。
IP报头

四位首部长度和我们的TCP是一样的0-15,单位是4个字节。
任何报头都得解决两个问题,一个是报头和有效载荷分离问题:此时我们16位表示总长度,4位标识报头长度,此时我们不就可以区分报头和有效载荷了吗。
看一下这个8位服务类型。

第二个问题就是如何做到向上层交付??
8位协议,就是标识上层协议的类型,我是交给TCP还是UDP呢??
就是在这里面存放的,都是有自己的编号的。
八位生存时间TTL,我们来理解一下。
我们报文路径的拓扑结构肯定存在环路问题,我们此时就不用担心我们的信号在远距离的传输过程中出现信号衰减的问题,因为集线器的存在,使得我们的信号能被一次次的放大。

如果我们的拓扑序列出现了环形的,此时由于集线器的原因,导致我们的这个信号能永生,此时如果永生的报文多了,路由器就会瘫痪,那怎么解决呢??
此时就出现了TTL,就是每经过一个路由器就--,减到0就自动丢弃。
再看我们的32位的源IP地址和目的IP地址,是四字节的IP并且sockfd=IP+port。
网段划分
运营商,搭建整个网络的基础设施。网络划分也是运营商做的。
怎么划分的呢??
IP地址是被精心设计过的,IP=网络号+主机号。
这个是唯一的,就是通过网络号+主机号我们就可以通过这个IP通过查路由表看看需要往哪个子网中去转,然后通过主机号找到对应的主机。
为什么我们通过这种方式为什么效率高,因为我淘汰的快,意思就是查一下网络号就知道你是不是该子网的,不是直接去下一个,不需要一个一个的主机找,导致很快。
网段划分就是把相同的放在一起通过网络号标识,划分网段就是为了提高效率。

两个不同的网段,我们路由器横跨两个网段说明它就肯定存在两个IP表去转换。
不同的⼦⽹其实就是把⽹络号相同的主机放到⼀起.
如果在⼦⽹中新增⼀台主机, 则这台主机的⽹络号和这个⼦⽹的⽹络号⼀致, 但是主机号必须不能 和⼦⽹中的其他主机重复.
通过合理设置主机号和⽹络号, 就可以保证在相互连接的⽹络中, 每台主机的IP地址都不相同.
那么问题来了, ⼿动管理⼦⽹内的IP, 是⼀个相当⿇烦的事情.
有⼀种技术叫做DHCP, 能够⾃动的给⼦⽹内新增主机节点分配IP地址, 避免了⼿动管理IP的不便.
⼀般的路由器都带有DHCP功能. 因此路由器也可以看做⼀个DHCP服务器.
过去曾经提出⼀种划分⽹络号和主机号的⽅案, 把所有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类⽆关;
举个例子理解一下这个。
提出新的就要看老的为什么不行了。

我们老的划分方案力度太粗了,意思就是我们老的的划分比如申请A类网络将会有2的24次方-2位置可以给主机分配主机号,但是不可能有这么多主机的,所以就造成了大量的浪费。
子网掩码的本质是为了提高分类划分发的IP地址的利用率。
这个是怎么实现的呢??
因为我们不同的公司如果申请A类网络,就是通过申请网络号的形式申请的,不同网络号就代表不同公司申请的A类地址,你后面的主机号是你能分配的主机号,这就有个弊端就是我们用不了这么多的主机号,所以出现了一个新的方式,就是我们可以把主机号拿出来几位来充当我们的网络号,此时你可以申请的网络变多了,主机变少了,主机变少没关系,因为我用不了这么多。看子网掩码多少个1就有多少个网络号。
就是你需要连接几个主机我就给你够放的主机位即可,比如我们要放60台主机,此时你只需要8位主机位即可放,此时前面24位都是网络号,此时你能申请的网络就变多了,此时这个是非常好的一个方案。

我们举了个例子,我们通过第二行就是子网掩码可以看出此时240 : 11110000这就是240,此时就可以看出网络号有28位了,主机号四位,[0,15]台主机,按位与就是有0则0,否则为1,但是由于我们主机号全0代表网络地址,全1代表广播地址,都是我们不能使用的,所以我们真正能用的只有13个。
特殊的IP地址
将IP地址中的主机地址全部设为0, 就成为了⽹络号, 代表这个局域⽹;
将IP地址中的主机地址全部设为1, 就成为了⼴播地址, ⽤于给同⼀个链路中相互连接的所有主机发
送数据包;
127.*的IP地址⽤于本机环回(loop back)测试,通常是127.0.0.1
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还没有普及;
私有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,只有内网IP!!
我们的家用路由器是帮助我们组建局域网。

我们连网本质就是来接路由器,然后就是路由器验证账号和密码,此时验证成功就会给你分配局域网的该网段的主机号,然后你就可以接入到我们的局域网就可以上网了。
比如我们家和邻居家路由的IP地址可以一样吗?
可以的。
等于说路由器是公网IP,路由给我们的是内网IP,不同路由器分配的内网IP可以相同不影响。
我们刷抖音,是抖音给我提供的服务啊,为什么我缺把钱交给运营商呢??
首先先思考,你老家是如何上网的??
不是你找运营商给你搞的吗??
那你家用路由器连接的是谁啊,一端连接的使我们家的子网,另外一段连接的是我们运营商,所以你才能上网。
其实真正是我们先连接到企业路由器,企业路由器是连接我们的运营商的广域网了。

这里的子网IP是供你家使用的IP,这个WAN口IP是运营商给我们提供的IP。
家用路由器的本质:其实是运营商路由器搭建的子网的其中一个主机节点。
意思就是,我们你家路由器,就只是它大号网络里的一台小主机 。运营商给你家路由器发了一个 WAN 公网 IP,怎么理解呢??
就是我们运营商给我们企业级路由器一个WAN口IP地址,这个地址是我们的公网IP地址,意思就是这个运营商和这个企业级路由器属于一个公网中的两个主机了,这个企业级路由器还有一个子网IP就是自己的内网IP了,此时把这个内网IP就给了我们家用路由器的WAN地址,此时我们的家用路由器和这个企业级路由器也相当于一个子网中的两个不同的主机了,此时我们的家用路由器也会有自己的子网IP供我们的电脑和手机使用,此时我们的电脑和手机连接同一个路由就是我们两台不同的设备也属于这个子网中的不同主机了,我们的手机和电脑不需要让谁再连接了,所以不需要再有自己的子网IP了,我们的WAN地址的作用就是,我们手机通过这个子网IP找到路由器,然后家用路由通过WAN地址找到企业级路由,然后企业级路由再拿着WAN地址就能找到使得我们手机连入公网了。
我们手机开热点就是也相当于建立自己的子网IP,然后供其他人使用,此时路由给我们的IP就是我们手机的WAN口IP。
客户端时如何发送数据给公网主机的??

此时dst时122.77.241我想去这个公网,但是我的IP时192.168.1.201,此时我一定能确认咱俩肯定不在同一个子网当中的,所以只能给路由器了,路由器再看自己的WAN地址看看是不是这个IP,不是的话继续交给上层路由器,通过WAN地址发现找到了。
私有IP只能构建子网,不能出现在公网,所以我们的路由器会把我们的私有IP转化为WAN地址,和我们上面讲的一样。
内网->公网这种技术叫做NAT技术。
公网我们怎么理解呢??
真实的⽹络结构⾮常复杂,即涉及到划分公⽹IP的组织,ICANN,还要在全球范围内进⾏区域划分, ⽐如亚太,北美,欧洲等,⼜要考虑各个国家内部的ISP代理,整体拓扑⾮常复杂,我们简化所有过程,简单理解公⽹即可 。

我们每个国家被分配的都存在公网,分配这个网络号就是为了把这个网络大蛋糕按人头平均到每个国家的,这个国际骨干网络就是我们所说的公网,我们每个国家还存在一个国际路由器,那这些国际路由器是怎么连接的呢??
可以用卫星或者海底光纤。
我们俄罗斯人想访问百度的过程就是,俄罗斯人通过输入www.baidu.com,此时的话就做域名解析工作,此时就拿到了我们百度的网络IP,是5开头的,此时就会看是不是本国家的, 不是的话就从国际路由出去,通过路由器中存在一个路由表, 然后判断我要去哪个国家的路由,然后通过海底光纤什么的进入到中国的路由,然后找到百度,然后再把这个报文发送回去,此时你俄罗斯人就能访问百度了。

我们每个省之间也要瓜分接下来的八位来代表我们不同的省,此时就区分了每个不容的省了,网络号都是十六位了,你从俄罗斯访问到河南其实就是两次子网划分,就是开始先划分了八位代表不同的国家吗,通过与八位网络号按位与看看是哪个国家的,然后发送到那个国家的国际路由,此时这个国家再拿着这个国际路由查看路由表,此时需要再次子网划分,子网掩码变成16位网络号了,此时子网划分按位与结束之后就能确定哪个省了。

此时我再用四个比特位去代表不同的市。此时给我们使用的话,运营商就可以通过这个市的公网IP继续构建子网IP供我们使用了,构建的子网IP的,WAN地址就是我们的这个公网IP了,此时就能接入公网。
主要通过上面这个例子理解一下子网划分的结构。

为什么省路由器没有WAN地址啊?
先分清:家用 / 企业路由 vs 省网核心路由
- 家用 / 企业路由(你熟悉的那种)
-
结构:1 个 WAN 口 + 多个 LAN 口
-
WAN 口:向上连运营商 / 上级,获取公网 IP 或上级内网 IP(你之前理解的 "WAN 地址")
-
LAN 口:向下发私有 IP,建自己的子网
-
角色:边缘网关,一头连外网、一头连内网
- 省网核心 / 汇接路由器(你说的 "省路由器")
-
结构:全是高速接口(GE/10GE/100GE),不分 WAN/LAN
-
每个接口:都配公网 IP ,直接参与全网路由计算(BGP/OSPF)
-
角色:骨干节点 ,只负责高速转发、跨区域互联,不做 NAT、不发私有 IP
二、为什么省路由器没有 "WAN 地址"?
- 它没有 "上级",只有 "对等 / 互联"
-
家用路由:WAN 口是下级连上级(你→运营商)
-
省路由器:所有接口都是同级互联(省网↔骨干、省网↔城域网)
-
没有 "谁给谁分配 IP",都是手动配置公网 IP,参与全网路由
- 它不做 "网关 / NAT",只做 "转发"
-
家用路由:WAN 口负责NAT 转换(私有 IP→公网 IP)
-
省路由器:不做 NAT,只查路由表、转发数据包
-
所有接口都是公网 IP,没有 "WAN/LAN" 的内外网区分
- 它是 "全网路由节点",不是 "边缘网关"
-
家用路由:边缘设备,负责把内网接入公网
-
省路由器:核心节点 ,负责省际 / 省内流量调度
-
它的 IP 是全网路由的一部分,不是 "上级分配的 WAN 地址"
我们的省路由是如何跨国通信的??
省路由存在一个国内各个省份的路由信息,如果查到这个路由信息不是国内的,此时就走缺省路由,缺省路由记录的就是我们中国的国际出口路由器,跳到我们的国际路由的话,此时就能查去它的路由表,然后看你要去的目的IP属于哪个国家。
我们家用路由是通过用WAN地址是去用来接入我们的公网的。
你的手机 / 电脑(内网),家用路由器 LAN,家用路由器WAN 口 上交流量给运营商,市级路由 → 省级路由 → 国家骨干 / 国际出口,出海到国外。
运营商大型骨干路由器 接口可以不同网段、不同网络号 靠「下一跳路由」强行点对点转发不需要处在同一个子网,就是它们路由器中都存在一个路由表存放着这几跳的信息。
查路由表只有三种结果。

缺省路由的意思就是默认路由,就是你访问其它路由器它们都不知道你要去的目的子网在哪,就是它们的路由表中都不存在这个信息,此时你就要走默认路由了,就是缺省路由,明确下一跳就是我们上面讲的跨国通信,就是我这个路由器知道你下个路由器要去哪里,下个路由器你要去哪个路由器都在我的路由表中记录着呢。最后一种情况就是已经到了。
我们通过route命令可以查本地路由表信息。

这是我们随便写的一个路由表,此时是怎么找的呢??
就是通过你的目标地址和我路由表中的每行的子网掩码按位与操作看看和前面的目的地子网是否相同,相同的话就是这个子网中的某台主机了,就进入这个路由即可。
这个default就是缺省路由,如果上面的都不符合,就走这个缺省路由。
IP报头

我们讲一下这个原理。
我们学习网络的本质就是学习一个报文的整个生命周期。

分片是干嘛呢??
就是我们数据链路层收到的IP报文大小不能超过1500字节,如果网络层拿到的报文超过这个数量了,此时不能直接发给数据链路层,而是需要先分片。
分片是发送方的网络层做的,组装是对方网络层做的。
这个16位标识就是我的这个报文如果分片了,就必须有相同的标识。

是如何分片和组装的呢?
首先考虑一个问题。

如果一个IP报文被分成了三部分(最前面是报头),此时每个分片的报文要不要带我们的报头呢??
答案是肯定要的,因为我们的报头中存在我们十六位唯一标识的标志位。

这是分片后的结果,每片都要有报头。
分片分的是有效载荷,就是正文内容或者说数据部分,报头是都需要带的。
思考一个问题,如果两个IP报文的有效载荷是3000个字节需要分为几片呢??
我就直接说结论了,不可能是两片,必须是三片,因为我们还存在报头呢,报头也是存在数据的,如果分成两片都是1500字节加上报头就超过1500了。
我们的报头还占20个字节呢,所以我们需要1480+1480+40这样子分片,然后我们的第一个片的片偏移量为0,第二个为1480,第三个为2960,都是相对于有效载荷的偏移量。

禁止分片就是不让报文分片,如果超过了1500就直接丢弃。
第三位标识的是否是最后一个分片,如果是1表示我后面还有分片,如果是0的话表示我后面没有分片了。
想知道如何分片,我们首先先了解如何组装,就是如何跳出来分片的报文?如何知道挑完整了呢?
就算你拿到了全部分片字段,怎么组装??
先回答第一个问题,如果该报文分片了,更多分片标志位一定是1!
最后一个分片为0啊,怎么办呢??
怎么和没有分片的区分呢??
通过片偏移,如果分片了片偏移一定大于0.
我从16位标识我就能拿到全部分片,怎么保证完整呢??
没有第一片?片偏移量看看是否有0,然后看更多分片标志位为0,此时就能保证头尾完整。
怎么确认中间很多片是否丢了呢??
按照片偏移量的数字做升序排序,此时看看有没有确实就能看是否完整。
其实真正的过程是按照十六位标志位拿完之后,直接升序排序,通过看看第一个的片偏移量是否为0,为0就开始看后面,每次+1480看看是不是下一个报文的片偏移量,最后一个我们只需要看看更多标志位是不是0即可判断。
此时完成了上面问题的回答,分片就是反过来这个过程即可。
谈两个细节。
如果我们数据分片的数据有部分丢了怎么办呢??
任意分片丢失,会导致整个报文全部丢弃,要求你重传。
如果上层是UDP,它不保证可靠性啊,他怎么保证重传呢??
分片会增加丢报概率,你比如你传一个报文的时候成功的概率是99%,如果分片为4个报文,此时全部成功的概率就变成四个99%相乘,此时成功率不就变低了吗??
IP通信过程中,分片并不能作为主流。
还有一个问题。

你片偏移量是13为表示的,最大值你才能表示到我们的2的13次方-1啊,但是我的数据是16位啊,我最多可以到达2的16次方-1处啊,此时你怎么表示我超过2的13次方的部分呢??
此时怎么办呢??
你可以让你的片偏移量/8,意思是啥呢??
就是你第二个分片的片偏移量一定是1480对吧,但是这样子的话不够表示,所以我可以让这个数/8,此时就是185,无非到后面的时候我重新*8恢复出来即可,所以此时你能表示的片偏移量的范围就变得更大了,为什么是8呢??
因为你的16和13正好相差2的3次方正好是8,刚好能把16位数据全部表示了。
举个例子是你原来能表示的范围是[0,16],此时你就只能接收0,16的数据,但是如果我们把发送过来的数据/8的话,此时你就能收到[0,128]个数据了,此时能表示发过来数据也就变多了。
只要你的数据是八的整数倍,此时你的二进制低三位一定是0,是无意义的,我们除8就是右移三位,此时就只保留有效数据,组装的时候无非乘以8左移三位就恢复过来。
分片有很多弊端,那为什么不能不分片吗??
分不分片不是我说了算的,而是网络层说的算的,因为数据链路层的接收能力有限,此时你传输层就别给我发太多数据了,减少我的分片。

这是上面遗留的问题,此时就能解答了,就是为什么不能一次把数据发送给对方,因为你发送的太多的话,我就要多次分片了,这是不好的。

此时我们数据链路层的有效载荷不能超过1500的意思就是我网络层的有效载荷不能超过1480,就要保证我的传输层的有效载荷不能超过1460,这个1460就是MSS:最大段尺寸了,我们传输层还有选项,如果带选项的话,内容就要变得更小了,反正1460就是我们能传输的最大载荷了。
此时网络层的内容就全部讲完了。