承接前文TCP协议-CSDN博客

简介

协议头格式

网段划分(重要)

划分方法

IP地址的数量限制(背景介绍)

私有IP地址和公网IP地址(提出解决思路)

NAT技术(解决方法)

路由

网络层

在复杂的网络环境中确定一个合适的路径

IP协议

主机: 配有IP地址, 可以认为就是你的电脑; 路由器: 即配有IP地址, 又能进行路由控制; 节点: 主机和路由器的统称;

基本认知

拥有数据将数据从A主机跨网络到B主机的能力,并且是择优选择,关于择优选择,我们做个比喻就知道了,比如我们去旅游,A在北京想去海南,这个时候我们可以知道,A有很多种去海南的路径(这里指的是经过的城市,而不是去往的方式),A可以径直向南经过石家庄、郑州、武汉等等城市向南走最方便的路线,但是你也可以向北走,反正地球也是圆的不是,但是这并不是最优的路线,那么在网络中秉着择优选择的道理,它是不会这样走的,它一定会选择最优的路线,来到达目的地

基于上述,就得引入两个重要的属性,目的IP和源IP,前者指的是我们要到哪里去,指的是海南,后者指的是你上一站的地址,并且在后续的介绍中会知道它是动态的,一直在改变

在一切的开始我们首先把结论说明再来详细介绍:ip = 目标网络 + 目标主机,用旅游的例子来说,目标网络指的就是海南,但是上面有一点没有说明的是,A去海南旅游并不是去这个省份,而是具体的某个城市,比如说三亚,这里的三亚指的就是目标主机,这就像A在去往海南的路上时,有人问他去哪里,A会回答说:去海南(目标网络),但是当A到达海南的时候,A的回答就会变成:去三亚(目标主机)

协议头格式

16位标识、3位标志、13位片偏移暂时不介绍,在最后介绍,这里面最重要的字段就是32位源地址和32位目标地址这两个了

同以往的思路,我们先解决两个问题:

1.如何将报头和有效载荷分离?

2.如何交付?

4位首部长度、16位总长度、8位协议

这里有一点和TCP不一样,为什么这里有总长度,但是TCP协议中却没有了呢?这是因为性质不一样,我们要明确认知到TCP是字节流,而IP则是以报文的形式进行传输,是一个一个的,因为我们无法保证收取到的报文是一个完整的报文,所有我们得有16位总长度来自描述,帮助我们确认是否收到了一个完整的报文。问题1得到解决

16位首部检验和

8位生存时间

虽然说只有8位,2^8一共256个数值,但是其实已经很大了,我们数据的路由通常也就几次就可以到达目标网络,至少是目前是够用的

32位源地址和32位目标地址

至于源IP这一点我们在后续会提到,这个是动态的,至于是说明时候填先的字段,这是在应用层就已经完成了,在bind套接字的时候,我们就已经表明,凡是从这个套接字出去的数据,都是从哪里来到哪里去,操作系统会自动帮我们完成绑定,这里的自动是说前面的绑定工作都正确实现的情况下说明的

4位版本号

至于IPv4现在看来是不够的,2^32,大约40亿个,实际上早就不够了,可能在国内都不够我们使用,而IPv6拥有了2^128位数值,这个数值号称连地球上的每一颗沙子都能够分配一个IP地址,那么为什么早期的建设是采用IPv4的呢?历史的局限性,就可以很好的解释了,早期的人们看来40亿是完全够用的,就像我们认为IPv6提供的IP地址是够用的一样

那么我们为什么不全部更新为IPv6呢?网络是一台已经发动的机器,是无法停下来的,这是底层的修改,通常我们修改都不会涉及到底层,并且IPv4它的更改是全球性的,影响太大,成本太高,以至于我们即使在IP地址不够用的情况下,还是选择不更新,这是本质原因,但是主要原因其实是因为有了解决方法,这一点后续谈及

还有一点原因需要我们了解,基于成本的原因,其实很多国家是无法进行修改的,只有经济实力雄厚,国际影响力大的国家才有资格推行,而我们知道IPv4是漂亮国的标准,IPv6是在颠覆IPv4的地位,其实现在我国在大力推行IPv6,并且属于领先地位,再则我国的人口基数很大,当国内普及了之后,那么国外就不能够忽视中国这个庞大的互联网群体了,他们也必须要反过来适配我们的网络,一旦领先会发生什么事情这里就不多说了,再则因为政策影响,其实国内的设备很多都是支持IPv6的,现在我们的路由器都是内置了IPv6的功能的,只不过我们现在一般是默认关着的

8位服务类型

3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0). 4位TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要

这个是路由器用来制定转发策略时候用到的,这里也就不深入了解了,只需要知道,最优路径不一定是最短的,还有可靠性的因素影响,8位服务类型就是基于这方面的考虑来让路由器自行选择转发策略

4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4;
4位头部长度(header length): 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位目标地址: 表示发送端和接收端;
选项字段(不定长, 最多40字节):;

关于16位标识3位标志字段、13位分片偏移的介绍我们放在了后面和MAC帧数一起,这样才好理解,当然还是那句话,最重要的字段就是32位源地址和32位目标地址,其他的都是赐予的

网段划分(重要)

为了方便理解我们首先理解下面几个模型,还是和以前一样首先理解为什么想要网络划分

类比于网络通信,就能够理解了为什么需要网络划分了

查找的本质就是排除,上述模型中,假如A是一个个人去排除找到丢失物品的人,那么这是效率极低的方式,但是一层一层的交付再向下递给,这样就实现了一次查找就排除一群对象,这样做查找效率就非常高

所以,互联网中的每一台主机,都要隶属于某一个子网! — 为了方便定位这个主机!

为什么方便是因为效率高,那这也是为什么需要子网划分了,至此就解决了为什么的问题

这也是为什么 ip = 目标网络 + 目标主机

那怎么办?怎么做到子网划分的呢?

这也是为什么国内的评论是会附带地址了,其实知道了子网划分的原理理解起来不是一件难事

目前上述就是子网划分的宏观理念,但是注意实际上肯定不是这样做的,实际上要复杂的多

网段划分(详细)

IP地址分为两个部分, 网络号和主机号;
网络号: 保证相互连接的两个网段具有不同的标识;
主机号: 同一网段内, 主机之间具有相同的网络号, 但是必须有不同的主机号;

不同的子网其实就是把网络号相同的主机放到一起;
如果在子网中新增一台主机, 则这台主机的网络号和这个子网的网络号一致, 但是主机号必须不能和子网中的其他主机重复;

通过合理设置主机号和网络号, 就可以保证在相互连接的网络中, 每台主机的IP地址都不相同

分析

那么问题来了, 手动管理子网内的IP, 是一个相当麻烦的事情

有一种技术叫做DHCP, 能够自动的给子网内新增主机节点分配IP地址, 避免了手动管理IP的不便;
一般的路由器都带有DHCP功能. 因此路由器也可以看做一个DHCP服务器;

打开设备中连接无线网络的属性中可以看到

实际上一台笔记本在一开始没有连接到网络的时候是没有IP地址分配的,也就是说没有被分配,当第一次连接之后才有的

就好比你去别人家里做客,用别人家的网络,首先你与他家的路由器建立连接,申请到了IP地址,你才能用他家的网络进行上网

划分方法

老式划分法

过去曾经提出一种划分网络号和主机号的方案, 把所有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类无关;

路由器内置了子网掩码,所以网络管理员其实就是在做配置子网子网掩码用来划分子网这些工作

所以全0和全1是不被使用的

子网掩码如何划分

特殊的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地址的,因为那是私网IP

这个拿家用路由器来说明,当你要入网的时候,你会提交一份请求,然后让运营商技术人员来帮你完成,其实入网是有一个办网的账号和密码的,之后交的网费都是通过这个账号来交的,通常是手机号,技术人员在开始就会把这个账号和密码配置进路由器,这个和我们上网连接的那个账号是不一样的,那个是用来连接的,不是上网的。实际上当你通过路由器进行上网的时候,它就会经过路由器,因为路由器配置过账号(最开始的那一个),所以当不欠费的情况下上网,它是直接会通过的,

运营商扮演的角色应该是基础设施建造者

这一块也可以看出,当你访问外网的时候,运营商可以直接对你的数据进行解读,发现你访问外网,那么它就可以直接掐掉你的请求,这就是墙,并且这是无法绕开的,因为这直接从物理上就隔断了,你的设备可没有直接与其他内容提供者直接相连的,甚至间接都没有

由此我们可以得知路由器做的事情

路由器:

1.转发

2.DHCP|组建局域网 — 体现在配置无线网络,设置网络名称+密码

3.NAT

并且路由器只能使用上面的私网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的服务器上. 这样的服务器可以在阿里云/腾讯云上进行购买路由;

这里的地址/24,这里的24就是掩码了,标识32位中前24位为1后续为0,参考掩码的定义就可以了解了

二进制为:11111111 11111111 11111111 00000000

将其转化为十进制,就是:255.255.255.0

分析类比于之前提到的模型来看

路由器拥有组建局域网的能力,你向上交付的数据到了运营商不一定就到了公网,可能还是在一个运营商路由器构建的子网中,它会继续向上交付

并且因为路由器横跨了至少两个网络,所以路由器会配置至少两个IP地址

子网IP(LAN口IP):指的就是自己构建的子网中的IP地址,自己是路由器,所以是.1结尾,对内;

WAN口IP:指的就是在外部中子网的IP地址,对外;

私有IP可以重复

到现在我们就可以知道了,私有IP是可以重复的,它只需要保证在本子网络中不重复就行了,所以我们就可以利用重复的网络进行上网了,从而解决了IP地址不够的问题

NAT技术

我们把上述的替换src源IP的技术称为NAT技术(Network Address Translation,网络地址转换)

细心的人可能会发现虽然我们可以做到数据请求到服务器,服务器响应返回给了路由器,那么路由器怎么把响应再返回给主机呢?在一开始我们就把主机的地址(src)给替换了的,其实NAT不仅仅是直接替换进行了,它还得保留一些东西,这一点我们得到后面才能揭晓了

实际网络划分(简化)

这里我们简易大区域划分了一下,这也是为什么像抖音、b站这类平台评论可以看到评论人的国家,在国内可以看到省份,那么不精确到市级别的原因也是因为进一步就是运营商的职务了,互联网平台有公网IP是可以看到数据是从哪一个地方传递过来的,前面提到服务器的响应是直接给源IP地址路由器的

衡量网络质量的其实就是我们所说的上下行速度,这都是明码标价的,大型互联网公司肯定需要的流量比我们普通用户需要的流量大得多。自然收取的费用也大的多

路由

怎么走?

在复杂的网络结构中, 找出一条通往终点的路线
路由的过程, 就是这样一跳一跳(Hop by Hop) “问路” 的过程.
所谓 “一跳” 就是数据链路层中的一个区间. 具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间

IP数据包的传输过程也和问路一样
当IP数据包, 到达路由器时, 路由器会先查看目的IP;
路由器决定这个数据包是能直接发送给目标主机, 还是需要发送给下一个路由器;
依次反复, 一直到达目标IP地址

拿问路举例子,当你向问一个人怎么去一所学校的报道时候会出现以下几种情况(只考虑问路情况)

第一种:不搭理你 —

在网络环境中,路由器不会拒绝你,所以不会出现不搭理报文的情况;

第二种:不知道,但是他知道谁知道,让你去问他 —

路由器不知道报文去哪里的情况下,在不确定的情况下一定得把报文交给下一个路由器,它一定得知道谁知道,知道下一跳,也就是默认路由器,这个被称为默认网关,每一个路由器都得配置一个默认网关;

第三种:知道怎么走,他可以直接告诉你怎么走,但是只知道方向,让你沿着方向走 —

路由器知道该怎么走,但是更多细节可能不清楚,知道下一跳路由器,它就会直接把报文转发到吓一跳路由器;

第四种:这个人就是学校的保安,他直接告诉你可以进去了,这时候你就会改口问,18号宿舍楼怎么走,他也可以直接告诉你怎么走 —

这就是代表你找到了目标网络,你进去问18号宿舍楼(简化了,实际上你还得去找老师),就是在找目标主机,学校的保安就是这个子网的入口路由器;

第二、三种在数据转发在网络中是常态,同时在第四种情况下我们发现,我们后面改口了,联想到问路,其实在一开始问路的时候,你是不会直接问学校(目标网络)的18号宿舍楼(目标主机)怎么走的,而是直接问学校怎么走;实际中在路由的过程中,我们只会看目标网络,只有找到了目标网络,再结合入口路由器(它会知道目标主机怎么走)之后我们才会开始找目标主机

在最后当你找到了目标主机(帮你报道的老师),其实你不是找他这个人,而是要这个人帮你办理入学手续,让他给你提高入学服务,这不就是要继续通过端口号找到这个进程,来让他给你响应吗?本质上就是进程与进程之间通信

怎么判断?

那么如何判定当前这个数据包该发送到哪里呢” />

路由表可以使用route命令查看

如果目的IP命中了路由表, 就直接转发即可;
路由表中的最后一行,主要由下一跳地址和发送接口两部分组成,当目的地址与路由表中其它行都不匹配时,就按缺省路由条目规定的接口发送到下一跳地址;

路由查表过程

转发过程例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路由器根据它的路由表决定下一跳地址

随着转发次数的增加,网络号回越来越长,越来越精细,直到找到了目标网络,所以我们要去的目标网络号是动态的

像那些互联网公司提高服务,是需要公网IP的

关于路由表生成算法自行去了解吧

组装和分片

在前面的介绍中,IP协议是负责数据传输的,但是我们得明白一点,其实真正在线上跑的其实是MAC帧,但是MAC帧协议中,自己的有效载荷不能超过 1500 字节(MTU,可以修改),即单个报文不要超过1500字节,其实 1500字节 = IP报文 + IP报文的有效载荷(还可以细分)

但是IP是无法决定单个报文的大小的!只有TCP(传输控制协议)才能决定,之前在介绍TCP的时候就有一个问题,在知道了对方的接受能力和拥塞控制的存在,为什么要把报文分成多个去发送,而不去选择一次性发送呢?其实就是因为这一层协议是不能够支持上层发送任意大小的报文的,关于这一点后续再详细介绍

基于上述的种种因素,因为数据链路层 无法接受过大的报文,并且只有传输层(TCP)才能控制发送的报文的大小(数据是可能超过MAC帧的限制,因为要发送多少,下层就得发送多少,即使会考虑,但通常也难免会出现大的报文),因为下层的大小限制所以IP协议需要自己分片,所以IP协议有了16位标识、3位标志字段、13位分片偏移这三个字段了,这个时候MAC帧是不关心上层IP传过来的数据是否进行了分片,它只关心是否超过了MTU(通常1500字节),发送方TCP也并不关心报文是否被分片了(关心了话就不会发送太大的报文了,笑~),接收方TCP同样也不会关心报文是否被分片了,发送方发送3000字节,接收方就接受3000字节,只在意是否收完整了,即使组装出错了也不关心

得出结论:分片与组装只是IP协议自己的行为,出错了也是自己解决

为此我们需要解决下面几个问题

0.你怎么知道一个报文被分片了?

1.同一个报文的分片都能够被识别出来收全

2.哪一个是第一个,哪一个是最后一个,有没有收全或者丢失合并

3.那个在前,那个在后,如何正确的进行组装

4.怎么保证我合起来的报文是正确的!

1、2点表明是否收全了,第3点表示合并过程

16位标识(id): 唯一的标识主机发送的报文. 如果IP报文因为数据链路层而被分片了, 那么每一个片里面的这个id都是相同的;
3位标志字段: 第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到). 第二位置为1表示禁止分片(通常为0,表示可以分片), 这时候如果报文长度超过MTU, IP模块就会丢弃报文. 第三位表示”更多分片”, 如果分片了的话,最后一个分片置为0,表示结尾, 其他是1,表示后面还有报文. 类似于一个结束标记,拿 \0 做结尾就可以很好的记住了;
13位分片偏移(framegament offset): 是分片相对于原始IP报文开始处的偏移. 其实就是在表示当前分片在原报文中处在哪个位置. 实际偏移的字节数是这个值 * 8 得到的. 因此, 除了最后一个报文之外, 其他报文的长度必须是8的整数倍(否则报文就不连续了);

我们还得明白一点是,即使被分片了,它们也还是一个个的完整的报文,每一个都有完整的报头,当进行组装的时候才会去掉

回答上述提及的问题

当这几个问题得到解决之后,得继续处理两个后续延申问题

Q:分片好吗?

A:显然是不好

Q:对TCP和UDP包括IP本身有什么影响?

A :一个报文被拆成了多个,任意一个报文分片丢失,就会造成拼接组装失败,进而导致对端对整个报文进行重传,并且因为实际传送的报文变多了,所以会导致丢包率变高了,因此分片不是主流行为

自己试着分片

至此网络层IP协议方面结束,下一期数据链路层