前言
通过上篇的UDP 和 TCP 我们知道了传输层的数据通过这个两个协议,对于不同的应用层,能够把数据交给用户,应用层的数据也能向下交付给我们传输层。
传输层本质还是在操作系统的内核,那么我们要在微信上发送消息,跨越主机必定要用到网络,对方主机收到我们发送的微信消息也是一样。
那么网络层是如何做到的?
需要IP
1. IP
我们学习IP之前先来了解几个前置知识。
1.1 前置知识
这个世界上有没有100%能成功的事?潜意识告诉我们可能没有,但是我想说的是,如果是一个通天的人,加上一个能力出众的人,他们两个组合去办一件事,那就是百分之一百。
在网络中光是靠TCP还不行,虽然TCP有很多可靠机制,但是TCP没有能力把数据跨网络发送。而TCP提供的是一种策略,一种可靠策略,让数据不丢失。所以我们需要一个能够跨网络传输的能力东西,而这个就是IP
IP协议的本质:提供一种跨网络传输的能力。
而我们用户需要的是:提供一种可靠跨网络传输的能力。
TCP和IP结合起来,就能保证每次传输的数据都能可靠的到达(前提是网络没有问题)。
IP 可不只是目标网络,它是目标网络+目标主机。 这个就好比,你去某个城市旅游,比如你要去西藏拉萨这个城市旅游。拉萨对应的就是你要去目标城市,但是拉萨很大,你要去拉萨那个地点游玩?比如布达拉宫。而这个布达拉宫就是目标地点。
那么对应网络来说,目标网络对应目标城市,目标地点对应目标主机。所以A主机给B主机跨网络发送消息,其实是先找到B主机的目标网络下的路由器,路由器然后再转发给目标主机。
到这里你就有疑问了,IP如何在这个网络中快速找到目标网络?
要知道我们生活世界,是一个被精心设计的过的世界,想一想你的身份证号码,不就是被精心设计的过的吗?
身份证号码的组成
中国身份证号码由18位数字组成,其中最后一位是校验码。前6位是地址码,代表公民所在的省、自治区、直辖市;接下来的8位是出生日期码,代表公民出生的年、月、日;再接下来的3位是顺序码,用于区分同一天内出生的人;最后一位是校验码,用于校验前17位数字的准确性。
IP也是同理,所以目的IP根据子网划分,一下就知道了目的IP的所在城市。
1.2 IP协议报头
老规矩 正式学习IP报头我们还是先从数据如何分离,如何向上交付给上一层?
4位版本:IPv4来说就是4位版本,我国现在一些企业用的是IPv6,出现IPv6是因为IP地址不够用了。IPv4 32个bit,而IPv6是128个bit。
4位首部长度:这个和TCP的4位首部长度是一个道理 【0000*4,1111*4】这个是2进制,那么转化成人类习惯的10进制【0,15】,而IP的固定长度是20个字节,那么如果有数据IP报文大小取值范围就是【20,60】。
16位总长度(total length): IP数据报整体占多少个字节
到这里你明白了有效数据如何分离,固定长度IP报头20个字节,加上自描述字段(4位首部长度+ 16位总长度 ) 有效载荷 = 自描述字段 - 固定长度。
8位服务类型(TOS):
8位生存时间(TTL):
如果一个报文长时间在网络中会怎么样?一个两个还好,如果是所有的报文呢?这会导致网络资源的浪费,并可能引发网络拥塞.
所以8位生存时间就是报文数据报到达目的地的最大报文跳数. 一般是64. 每次经过一个路由, TTL -= 1, 一直减到0还没到达, 那么就丢弃了. 这个字段主要是用来防止出现路由循环。
还剩下这3个我们后面讲
1.3 网段划分
如上图所示:IP地址分为两个部分,网络号和主机号。
网络号:保证相互连接的两个网段具有不同的标识。
主机号:同一网段内,主机之间具有相同的网络号,但是他们的主机号一定是不同的。这个就好比是班的学号一样。一个班40个人那么他们的学号前面一定固定的,而最后两位一定是不同的。
- 不同的子网其实就是把网络号相同的主机放到一起.
- 如果在子网中新增一台主机, 则这台主机的网络号和这个子网的网络号一致, 但是主机号必须不能和子网中的其他主机重复.
上图的路由器是连接了两个子网,一个是192.168.128 另一个是192.168.144,那么意味着路由器具有多张网卡,所以才能配置多个IP,有了多个IP就能保证路由器同时在两个以上子网的中。
同时路由器也具有构建子网的能力,因为路由器本质也是也是一个特定的子网主机。
通过合理设置网络号、主机号,就可以使相互连接的网络中,每台主机的IP地址都不相同。
那么这里就这就有一个问题了?如何管理这些IP?
如果我们手动管理这些IP地址,确实是一个相当麻烦的事。
有一种技术叫做 DHCP, 能够自动的给子网内新增主机节点分配 IP 地址 , 避免了手动管理 IP 的不便 .一般的路由器都带有 DHCP 功能 . 因此路由器也可以看做一个 DHCP 服务器 .
过去曾经提出一种划分网络号和主机号的方案, 把所有IP 地址分为五类, 如下图所示(该图出自[TCPIP])。
- 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
当时这样划分存在局限性,毕竟那个时代,也不会想到如今七八十的大爷也会上网刷抖音快手。前面说过IPv4 是32个bit位,最大值也就是2的32次方,那么就是42亿多一点,那么全球80多亿人,明显不够。
而且这样划分弊端也很明显,比如说A类,7位网络号,24位主机号,那么一个A类子网段可以有1.6亿个IP地址,如果一个地区人口比较少,那么就会造成严重的浪费,本来资源就不够。
而B类比较好申请,网络好比较多,这就导致了B类快速被申请完了,而A类却有大量的浪费。
C类就会造成一个地区的IP严重不足。
针对这种情况提出了新的划分方案, 称为CIDR(Classless Interdomain Routing):
- 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号;
- 子网掩码也是一个32位的正整数. 通常用一串 "0" 来结尾;
- 将IP地址和子网掩码进行 "按位与" 操作, 得到的结果就是网络号;
- 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关;
下面以这个图为例:
子网掩码为255.255.255.0 这个是10进制的。255转化成2进制,那么就是1111 1111,3个255 就是24个1 然后在用0000 0000 补齐32位。
子网掩码二进制就是
1111 1111 1111 1111 1111 1111 0000 0000
那么我们利用按位与操作
140.252.20.68
&
1111 1111 1111 1111 1111 1111 0000 0000
就得到了网络号
140.252.20.0
- 将IP地址中的主机地址全部设为0, 就成为了网络号, 代表这个局域网;
- 将IP地址中的主机地址全部设为1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数据包;
- 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1
子网掩码 并没有实质性的解决IP地址不足的问题,IP地址并非是按照主机台数来配置的, 而是每一个网卡都需要配置一个或多个IP地址. 前面所说的路由器就需要配置多个IP
子网掩码解决浪费了问题,有了子网掩码 就可以对IP32位进行任意的划分。
1.4 私有IP地址和公网IP地址
如果一个组织内部组建局域网,IP只用于局域网内的通信,而不直接连到Internet上,那么从理论上来讲,任意的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却是不一样的。
- 一个路由器可以配置两个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是不能出现在Internet上,那报文是怎么到公网的?
以上图为例,我们地址是192.168.1.201 而/24 其实就是子网掩码(255.255.255.0)当我们手机应用层也就是APP 对 APP所对应的服务器进行请求时,那我们的请求由OS变成报文,层层向下交付,到了网络层,IP报文源IP就是192.168.1.201 报文交给路由器,而路由器跳转到下一个时会将源IP改成10.1.1.2 到了运营商路由器时,源IP地址变成了122.77.241.4 也就是说路由器每跳转一次,源IP地址就会变成当前要跳转路由器的WAN口IP。而这个替换的过程就是NAT技术。
而到了运营商路由器时,此时IP地址就变成了公网IP.
1.5 理解运营商和全球网络
第一个问题 我们是怎么上网的?
在生活中我们要上网,得有网,如何有网?回想你家第一次上网时,是不是先找运营商光纤入户?
入户之后给你一个账号和密码,光纤连接路由器,光纤传递是光信号(模拟信号),我们电脑手机并不认识,所以你家中还有一个设备——调制解调器。也就是人们常说的光猫。
光猫将模拟信号转化成数字信号,路由器连接光猫。
,你的电脑通过网线连接路由器,而这个网 通过上面的操作你的设备就连接了这个所谓的网——互联网。
运营商修建了大量的通信基础设施,使得全国的网络连接在一起。而这个工程只能是由移动电信联通来干,毕竟前期投入的成本太多。私人企业不会干这个事,试问10多以后才可能赚钱的事,你会不会干?
同样的道理各国也有类似的运营商,他们修建大量的通信基础设施,使得全球的网络连接到一起。
前面讲过IP是一份大的公共资源,全球是如何来划分这个资源的?
下面用一张图来解释
你可能会好奇 那我们的发送的消息, 相隔千里是如何快速的到对方的手机?
红色框起来的就是你当前路由器要去的下一跳 根据前面网段划分 你要发送的报文IP地址明显不是本地局域网,一对比就知道肯定是其他网段的,那么本地路由会交给同网段的路由器。直到到对方IP地址的局域网为止。
2.MAC
我们的报文既然通过了网络层能够远距离跨网络传输到对方主机,为什么有了IP还要有MAC地址?
都说跨网络,难道就没有局域通信吗?如果是在家里 你爸妈在微信上给你打电话叫你起床吃饭,3个手机都是处于同一个网段中,IP地址相同,你爸妈发送的微信消息如何能够送到你的手机上?而不是你爷爷奶奶的?
所以基于上面这种情况我们需要一种在局域网中通信的工具,它就是MAC。
实际上 在一台主机中,报文并没有通过网络层直接就发送了,而是传接到下一层也就是数据链路层。
而数据链路层解决的是直接相连的主机数据进行交付的问题。MAC地址是区分同一个局域网中,区分特定的主机。
老规矩学习MAC 我们还是从报文格式开始。
- 源地址和目的地址是指网卡的硬件地址(也叫MAC地址), 长度是48位,是在网卡出厂时固化的;
- 帧协议类型字段有三种值,分别对应IP、ARP、RARP;
- 帧末尾是CRC校验码。
以太网也是一样 采用固定长度+自描述字段组合 目的地址 源地址 类型 CRC 这些都是固定长度。
而数据的长度 是自描述的 IP发送多少数据来下,而多少数据对应了多大的长度。
细心的你发现了数据区间范围是46 ——1500,这个就是MAC帧发送数据的最小值 和 最大值。
也就是说减去MAC帧报文封装信息,IP一次最大只能发送1482个字节。
到这里我们就需要把IP报文遗留问题解决了
IP 16位标识 3位标志 13位片偏移
在IPv4协议中,IP数据报的报文头包含一个16位的标识字段(Identification),其主要作用是用于分片和重组。
-
作用:
-
当一个较大的IP数据报需要通过网络传输时,如果网络的MTU(最大传输单元)小于数据报的大小,数据报会被分片成多个较小的片段。
-
每个分片都会保留原始数据报的标识字段值,这样接收端可以根据相同的标识字段值将这些分片重新组合成原始数据报。
-
例如,一个较大的数据报被分成了3个分片,这3个分片的标识字段值是相同的,而它们的分片偏移(Fragment Offset)字段值不同,用于指示每个分片在原始数据报中的位置。
-
3位标志位的含义如下:
-
第1位(最高位):DF(Don't Fragment),表示“不分片”标志。
-
如果DF位为1,表示不允许对数据报进行分片。如果数据报太大无法通过网络传输,会直接丢弃。
-
如果DF位为0,表示允许对数据报进行分片。
-
-
第2位:MF(More Fragments),表示“更多分片”标志。
-
如果MF位为1,表示后面还有更多的分片。
-
如果MF位为0,表示这是最后一个分片。
-
-
第3位(最低位):保留位,通常为0,用于未来扩展。
分片偏移的作用
-
指示分片位置:分片偏移字段用于指示每个分片在原始数据报中的起始位置。接收端可以根据这个偏移值将分片重新组合成原始数据报。
-
确保正确重组:通过分片偏移字段,接收端可以确定每个分片的顺序,从而正确地将分片拼接在一起。如果分片偏移值不正确,可能会导致数据报重组失败。
通过这三个 我们就知道报文被分片没有,那些是同一组的以及如何组装。
报文会有丢失情况,更何况一个报文还被分成更多的分片,丢失的概率更大。那如何确定分片丢了?
如果丢失的是第一个?
我们收到最后一个分片,进行组装时,根据片偏移数据对不上,那么也意味着第一个丢了。
如果是中间的?其实也是一样。
如果是最后一个?
最后一个片偏移没有用,因为前面的数据都是对上,但是我们可以根据3位标志,最后一个分片的报文3位标志的第3位一定是1,如果我们没有收到这个,那么最后一个分片一定丢失了。
注意:
每个分片都要加IP的报头的
不管是第一个还是中间亦或者是最后只要丢失都要重发。
所以并不建议分片。
但是的但是
回想前面我们讲的MAC帧 这就导致了会倒逼IP 会进行分片。
2.1 认识MTU
MTU相当于发快递时对包裹尺寸的限制. 这个限制是不同的数据链路对应的物理层, 产生的限制.
- 以太网帧中的数据长度规定最小46字节,最大1500字节,ARP数据包的长度不够46字节,要在后面补填充位;
- 最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU;
到这里你明白了 前面讲的滑动窗口,既然能一次发送,为什么窗口内还会分划,那是因为MUT。
2.2 局域网通信原理
局域网中 如果一个人发送消息,其他人是发送不了的。这就是为什么你在人多地方上网比较网卡原因。
基于这种情况,自然会有一些算法来减少碰撞。当然物理上也有交换机。
交换机 作用就是 划分碰撞区域 ,你可以理解成一个局域网被分成好几个区域。处在同一个区域内发送消息不影响其他区域。
那如果是跨网络传输?
如果是跨网络传输 你就不要单纯的认为,发给路由器就完事了。
主机A 的报文要 发送 给 主机B 我们还是从网络协议栈来说
应用层 发送消息 到了 传输层 经过封装TCP报头,然后到了 网络层 IP也是同样封装报头,数据链路层也是同样封装MAC报头。然后发送给路由器1 路由1 拿到报文解析到网络层,确定IP地址不是本网段的,然后同样在它自己的网络层重新封装IP报头,数据链路层也是一样重新封装MAC报头。以此类推到了路由3。
这时就会有了一个问题了,毕竟是跨网络了,你路由器3怎么知道主机B MAC地址?
路由器3 确实不知道 主机B的MAC地址,只知道主机B的IP地址,所以我们需要在局域网中将主机B的IP转化成主机的MAC地址。
所以我们需要一种协议,而这个协议就是ARP协议。
2.3 ARP协议
ARP协议的作用主要是建立主机IP地址和MAC地址的映射关系。
- 源主机发出ARP请求,询问“IP地址是172.20.0.2的主机的硬件地址是多少”, 并将这个请求广播到本地网段(以太网帧首部的硬件地址填FF:FF:FF:FF:FF:FF表示广播);
- 目的主机接收到广播的ARP请求,发现其中的IP地址与本机相符,则发送一个ARP应答数据包给源主机,将自己的硬件地址填写在应答包中;
- 每台主机都维护一个ARP缓存表,可以用arp -a命令查看。缓存表中的表项有过期时间(一般为20分钟),如果20分钟内没有再次使用某个表项,则该表项失效,下次还要发ARP请求来获得目的主机的硬件地址
既然是协议 当然就会有相应的格式
ARP数据报的格式
- 注意到源MAC地址、目的MAC地址在以太网首部和ARP请求中各出现一次,对于链路层为以太网的情况是多余的,但如果链路层是其它类型的网络则有可能是必要的。
- 硬件类型指链路层网络类型,1为以太网;
- 协议类型指要转换的地址类型,0x0800为IP地址;
- 硬件地址长度对于以太网地址为6字节;
- 协议地址长度对于和IP地址为4字节;
- op字段为1表示ARP请求,op字段为2表示ARP应答。
在ARP的过程中,所有的ARP报文都是先看OP,因为OP决定了报文类型,如果是1,看的就是目的以太网地址,目的IP地址。
如果是2 看的就是发送端的以太网地址,发送端的IP地址。
2.3.1 ARP周边问题
ARP并不是到了标目主机的局域网才会进行,而是在来的路上就有会请求和响应。所以主机的MAC地址和IP地址都会被主机缓存起来。一般缓存时间几十分钟不等。缓存起来也就意味着不会在用ARP,ARP只有在缓存失效的时候才会生效。
一台主机可以通过自己的IP地址和子网掩码,经过按位与操作得到自己当前网段的网络号,然后通过ping命令 可以从1 到 254 的主机中 分别得到他们的IP 和 MAC地址。
如果一台主机收到多次同样的arp应答,这台主机会以最新的为准。
基于前面讲的,一台主机通过ARP 然后ping 得到同网段的所有主机的IP和MAC,那么我们就可以伪装成路由器,将路由器的IP地址改成自己IP地址,然后ARP请求中将发送端IP地址填写为路由器的IP地址,MAC地址还是自己的。一直大量重复的给同网段的主机发送ARP请求,那么同网段的主机收到我们的请求,发现是多次同样的就会更新ARP缓存,那么对方下次上网时访问互联网时,就会断网,因为他的报文是到了我们这台主机,而我们收到了之后并不会做处理,而是丢弃了。而这个过程就叫做ARP欺骗
同样的道理 我们也可以伪装成其他主机来欺骗路由器。
3. 其他重要协议或技术
3.1 ICMP协议
ICMP正是提供这种功能的协议; ICMP主要功能包括:
- 确认IP包是否成功到达目标地址.
- 通知在发送过程中IP包被丢弃的原因.
- ICMP也是基于IP协议工作的. 但是它并不是传输层的功能, 因此人们仍然把它归结为网络层协议;
- ICMP只能搭配IPv4使用. 如果是IPv6的情况下, 需要是用ICMPv6;
ICMP的类型含义
3.2 NAT技术
前面讲过我们大部分人使用都是私有IP,而私有IP是不能出现在公网的,而IP地址不够用的情况下产生了NAT技术,前面已经说过从内网到到外网,通过NAT不断变化IP地址,最后能访问服务器,但是服务器响应回来的时候并不知道我们的IP地址,如何发送报文回来?
答案是IP地址+端口号
同一个局域网中 IP地址一定是不一样 端口号可能相同,这时我们可以将它们的IP和端口号 整体看成一个字符串。而这个字符串在这网段中就是唯一的,那么同一个网段中ABC三台主机如果访问同一个服务器,比如抖音的服务器, 这时NAT路由器会将它们的IP+port 做成一个映射表如下图所示。它们互为键值,NAT不仅仅只替换IP地址,也会替换port 。同样的道理一直到公网的路由器到服务器为止。响应回来时,就知道了它们的ip地址。
NAT技术的缺陷
- 无法从NAT外部向内部服务器建立连接;
- 装换表的生成和销毁都需要额外开销;
- 通信过程中一旦NAT设备异常, 即使存在热备, 所有的TCP连接也都会断开;
3.3 代理服务器
代理服务器 分为两种 一种正向 一种反向,
正向代理:你叫小明去给你代购,他给你代购成功,海外超市直接发货给你。
反向:经过你的介绍 大家都叫小明去代购,小明嫌麻烦,直接自己开了一个工作室,以后有代购直接从工作室发货。
原本10.0.0.1 压力过大,分配给10.0.0.3 而这个10.0.0.1就如同原来超市,10.0.0.3就是小明。
总结:
通过本篇我们学习了IP报文格式,IP本质作用是跨网络运输,其中通过IP来划分网段,因为IP地址不足导致了出现私有IP和公网IP,它们的作用,最后理解了全球网络是怎么连接在一起的。
然后学习了数据链路层。其中因为网卡,导致一次数据发送只能是1500字节。认识了MTU,最后把IP遗留的分片问题解决了。了解局域网是通信的。以及了解了ARP的作用。
最后了解了一些其他技术。