网络层

  • 1、基本概念
  • 2、IP协议报头
  • 3、网段划分
  • 4、私有IP地址和公网IP地址
  • 5、路由
  • 6、IP分片和组装

1、基本概念


如图,以主机B和主机C通信为例,主机B和主机C并不是直接连接的。所以主机B给主机C发送数据需要交给路由器F、路由器G、路由器H、路由器C、路由器D,最后再由路由器D将数据发送给主机C。所以这里就会面临两个问题:
1、凭什么要交给下一跳路由器的问题(路径选择的问题)。
你要将数据千里迢迢的从主机B发送给主机C,那么你为什么要将数据交给路由器F、G、H…呢,路由器G和H、E都是直连的,为什么交给H而不交给E呢?这是为什么的问题。此处需要引入一个IP地址的概念,我们暂且理解为全网内具有唯一性的IP(公网IP)。所以通过IP标识全网的唯一一台主机C,主机B未来就可以通过某种算法进行路径选择,而进行路径选择的最重要标识就是主机C的IP地址。

2、怎么把数据交给路由器F的问题。怎么办的问题。
我们要知道主机B和路由器F是一个子网,而路由器F和路由器G也是在一个子网里面的,后面同样如此。因此网络通信的本质是通过一个一个子网进行传输的。

问题1对应的是网络层(IP)的问题,问题2对应的是局域网通信的问题。而局域网通信我们在网络基础概念已经说过了,因此今天的重点在于网络层。

关于IP地址分为两类:IPV4和IPV6。
IPV4:32位地址​​,通常以点分十进制表示,例如:42.194.197.13。其中每个8位的返回是0~255,所以就是:[0,255].[0,255].[0,255].[0,255]
IPv6:​​128位地址​​,以十六进制表示,用冒号分隔(例如:2001:0db8:85a3::8a2e:0370:7334)。
IP地址能表示主机的唯一性。

我们以唐僧取西经为例,唐僧最终要去的目标是西天的大雷音寺面见佛祖,但是唐僧在到达西天之前都会跟别人说我要去西天,比如唐僧在女儿国会说我要去西天,那么我该怎么走呢?而当唐僧到了西天,唐僧就会说我要到大雷音寺,请问该怎么走呢?在我们现实生活中也是如此,今天你要从云南去北京天安门广场,那么你问别人就会说,我要去北京请问该怎么走呢?一直到你到了北京,这时候你问人就会说,我要去天安门广场,请问该怎么走呢?在这个过程中,在路上我们选择的是北京进行路由,当到了目的地我们采用的是故宫进行路由。
实际上IP地址是被分成两部分的,IP地址=目标网络+目标主机

主机:配有IP地址,也要进行路由控制的设备。
路由器:既配有IP地址,又能进行路由控制。
节点:主机和路由器的统称。上面主机B到主机C这一条路径上的主机和路由器我们都可以成为节点。


重谈TCP和IP:

我们的数据经过传输层,添加了传输层如TCP报头后是要继续向下层交付的,然后网络层继续封装网络层报头,数据链路层也是如此,而同层之间认为自己在和对方直接通信。
我们把传输层的报文叫做数据段、网络层叫做数据报、数据链路层叫做数据帧。

IP核心作用:把数据包跨网络转发给目标主机!
如果丢包了呢?IP不关心,这是传输层TCP的事情,TCP没有收到应答就会进行超时重传。

IP提供了一种能力,把数据从A主机跨网络转发给B主机。但是有能力就一定能做到吗?有能力只是代表着有非常大的概率做到。
假设你们学校有个能力很强的张三,张三数学有考150分的能力,但是这并不意味着他能100%考150分,可能他这次考了148,147等。那么就存在一个教学主管,教学主管说为了让张三考满分,我们每次考试如果张三没有满分,我们就成绩作废全部重考。那么这样就保证了张三每次考试一定能考满分,因为如果没有满分就会重考,直到满分位置。
上面的教学主管就是TCP,张三就是IP,通过TCP+IP:提供了一种可靠的能力,把数据从A主机跨网络转发给B主机。而重考就是TCP的超时重传机制。TCP做的是策略的问题,比如之前的超时重传、确认应答、滑动窗口、拥塞控制等。IP做的是具体的转发。它们之间结合就能提供可靠的发送数据的能力。


2、IP协议报头


IP报头和TCP报头很相似,前面20字节固定长度,可以携带选项,然后后面就是有效载荷了。
1、如何进行解包和封包?
首先读取固定长度20字节,然后提取出4位首部长度。这里的4位首部长度跟TCP是一样的,取值返回是0000->1111,也就是[0, 15],是有基本单位的,基本单位也是4字节,所以长度范围就是[0, 60],而IP报头固定有20字节,因此IP报头的取值范围就是[20,60]。比对4位首部长度计算的值和20字节,如果大于20字节就在将选项读取上来,如果刚好20字节就说明不携带选项。另外IP报头中还存在16位总长度,因此IP报文也可能存在多个报文粘在一起的情况,所以可以提取出16位总长度,然后减去4位首部长度,就可以将有效载荷准确的读取上来。而TCP不存在总长度,因为TCP是面向字节流的,应用层要自己解决粘包问题。
因此IP的解包就解决了,那么封包也就不是问题了。

2、如何做到分用?
IP报头中8位协议字段,传输层UDP和TCP协议在操作系统内是有协议号的,TCP的协议号6,UDP的协议号是17。因此填上8位协议号,将来进行分用的时候提取8位协议号就知道要将有效载荷交付给上层的哪个协议了。

4位版本号(version):指定 IP 协议的版本,对于IPv4来说就是4。

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

8位生存时间(Time To Live, TTL):数据报到达目的地的最大报文跳数。一般是64。每次经过一个路由,TTL -= 1,一直减到0还没到达,那么就丢弃了。这个字段主要是用来防止出现路由循环。
8位生存时间是一个计数器,每经过一个路由器计数器做--。

16位标识、3位标志、13位片偏移到后面IP组装和分片再谈。


3、网段划分

有了目的地址是不够的!
比如今天我要从云南到北京,你想去就能去吗?这是因为从云南到北京修了路,从云南到北京的各种路段都是被设设计过的,所以你可以到北京。因此路是被设计过的。

而IP报文光有目的IP是不够的,网络也是被设计过的——子网划分。
那么网络被谁设计的呢?——网络服务提供商ISP,在我国就是三大运营商:移动、电信、联通。


如图存在了两个子网,上面子网的主机都是以192.168.128开头的,所以上面的网络号是:192.168.128.0。下面子网的主机都是以192.168.144开头的,下面的网络号是:192.168.144.0。而路由器横跨两个子网,因此路由器也要有两个IP地址(可以理解为两张网卡)。如果将来上面的子网要新接入一台主机,那么就需要给这台主机分配一个IP地址,而这台主机的IP地址就分为网络号+主机号。因此,IP=网络地址+主机地址。
网络号:保证相互连接的两个网段具有不同的标识。
主机号:同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号。

子网内的IP地址,都是从哪里来的?谁给它的?
谁是我们家里第一个入网的设备?——路由器!而路由器具有构建子网的功能!所以IP地址是路由器给的,当我们要上网的时候,就需要先连接路由器,这个过程就会申请IP地址。路由器的网络标识一般都是固定的,然后主机标识是1,因为路由器是第一台入网的设备。所以路由器给上下两个子网都分配了网络标识,而路由器在这两个子网中的主机标识都是1。

这里的IP地址实际上是内网IP。那么当获取到一个IP地址如何直到他的网络号呢?
比如192.168.128.18,因此会有这种写法:192.168.128.18/24,24代表的是前24位是网络号,后面的就是主机号,这是子网掩码的划分方式。

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

假设今天上面子网的主机:192.168.128.11要发送数据给192.168.144.10,那么上面子网的主机就会先将IP:192.168.144.10网络号提取出来,然后跟自己的网络号对比,如果是相等的,说明要发送的主机跟自己在一个子网内,所以就是局域网通信。如果不相等,它也不知道这台主机是谁,但是它知道这台主机一定不在这个子网中,所以它会将数据交给路由器,然后路由器再转发给192.168.144.10。
所以一个IP地址被转发:
1、根据目标网络,转发报文到目标网络。
2、转发到目标网络之后,把报文进行内网转发。


我们在大学里都会有一个学号,这个学号会标识唯一的一个学生。但是这个学号又会由几部分组成,比如哪一年入学的、哪一个学院、哪一个专业、哪一个班级,最后是你在班级中的编号。所以IP地址就类似学号,学号是由几部分组成的,IP地址是由目标网络+主机号组成的。下面我们举个例子,不过为了简便,我们只考虑学院编号+学生编号:

计算机学院的编号为01,理学院编号为02以此类推。而我们一般一个学院会建一个群,方便学院通知什么事情。所以你们学院的所有学生在一个群里,另外学院还会有一个院学生会主席,其他学院也是如此,而院学生会主席它们也会有自己的一个群,方便各个院学生会主席沟通。
假设张三是计算机学院的学生,它的学号就是01123,其中01表示学院编号,123表示他在计算机学院中的编号,对于其他学生也是如此。那么计算机学院的学生会主席也会有编号,比如01110。今天张三在学校里面捡到一个钱包,这个钱包有一些钱还有几张卡,其中就包含了学生卡,学生卡记录了关于学生的许多信息,但是很不巧,其他字段都模糊了,只能看到学号06321。那么张三就需要寻找失主了,张三到学校门口守着,来一个就让他背一下自己的学号,如果背对了就还给他,但是这种方式效率非常低,一个学校里面有好几千人,这样子就得花很长时间才能找到失主,而这个过程本质就是在线性遍历。另外一种方式:张三根据学号06321,他也不知道这个人是谁,但是张三可以肯定06开头的学号,肯定不是计算机学院的学生,因为自己的学号是01开头的,所以是其他学院的学生,张三就把这学号拍个照,然后加上自己的电话号码,在计算机学院的群里@一下学生会主席。学生会主席看到了之后就会把这个信息再在校群里面发一下,那么这时候机械学院的学生会主席看到了之后就会发现06开头不就是我们学院的吗,因此机械学院的学生会主席就会在自己的院学生群里说一声:谁的钱包丢啦,学号为06321,丢了的同学可以联系这个…电话。然后机械学院的李四就发现这不就是自己的学号吗,最终就找到了失主李四。
每个学院的群就是一个内网/子网/局域网,而学生会主席之间的群就是一个公网。张三发的学号06321+自己的电话就是报文,学号就是目的IP地址,自己的电话就是有效载荷。

1、为什么要这么做?
这个过程本质就是查找,查找的本质就是淘汰。第一种方式张三是一个人一个人的淘汰,而第二种方式张三一下子就能把理学院、经管学院等其他学院都淘汰了,迅速定位到机械学院。所以淘汰的效率就提高了,那么查找就快了。

2、在进入目标子网之前,张三和计算机学院学生会主席关心06321中的321吗?不关心,只关心06。——报文在转发的过程中,在到达目标子网之前,路由只看IP地址中的目标网络部分。

3、到达目标子网,才开始关心06321中的321,做内网转发。

4、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类无关。


IP地址和子网掩码还有一种更简洁的表示方法,例如 140.252.20.68/24,表示IP地址为140.252.20.68,子网掩码的高24位是1,也就是255.255.255.0。


特殊的IP地址:
1、将IP地址中的主机地址全部设为0,就成为了网络号,代表这个局域网。
2、将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包。
3、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地址的绝对上限并没有增加),仍然不是很够用。这时候有三种方式来解决:
1、动态分配 IP 地址:只给接入网络的设备分配IP地址。因此同一个MAC地址的设备,每次接入互联网中,得到的IP地址不一定是相同的。
2、NAT 技术(后面会重点介绍)。
3、IPv6:IPv6并不是IPv4的简单升级版。这是互不相干的两个协议,彼此并不兼容。IPv6用16字节128位来表示一个IP地址。但是目前IPv6还没有普及。


4、私有IP地址和公网IP地址

如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,理论上使用任意的IP地址都可以,但是RFC1918规定了用于组建局域网的私有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只能用来组建内网,不能出现在公网中。

在Windows终端中输入ipconfig:

我当前连接的是学校的网络,所以这个IPv4地址就是学校给我这台电脑分配的一个内网IP地址。由于学校人比较多,所以使用10.*开头来组建内网。如果在家里,一般就是192.168开头的,并且大家家里都是192.168开头的内网IP地址,内网IP地址是可以相同的。
私有IP只在内网中使用,所以不同的子网IP地址可以重复使用。公网IP不能出现重复!
网络假设的时候,在内网和公网中,统一采用各自的子网掩码的方式进行网络建设。

最常见的构建子网就是在家庭中,路由器构建一个子网,路由器有构建子网的能力。
局域网,子网不仅仅我们在做,运行商也在做!


1、基本网络情况:

首先,申请IP,无论是公网IP还是内网IP,网络建设工作都是由运营商来做的,国内最常见的就是移动、电信、联通。
如图,红色方框构建了一个家庭子网,而我们想要入网都是要打电话给运营商,然后运营商就会派个人过来,给我们装上猫、路由器,从最近的地方拉一条线过来。通过路由器构建一个子网,所以我们就可以使用手机、电脑连接路由器,就可以上网了。那么对于下面的就是同村的其他人家也构建的一个子网,对于右边就可能是其他镇的人家构建的一个家庭子网。并且我们注意到,红色方框构建的子网的内网IP和右边的内网IP是相同的,因为内网IP可以重复。路由器具有构建子网的能力,要先有路由器才能构建子网,我们才能连接路由器上网,所以路由器的子网IP地址一般都是xxx.xxx.xxx.1。

从我家路由器出去的报文,并没有直接到达公网,而是必须先到达运营商构建的一个更大的子网中。
在上图中,家里的路由器不仅是我们家中子网的一部分,还是另外一个更大的子网中的一部分,其他家也是如此。这个运营商路由器可能就是市里的一个大的子网,有十几万家的路由器和这个运营商路由器组成一个更大的子网。所以路由器是分为家用路由器和企业路由器的。
我们家用路由器横跨了两个子网,所以它有两个IP地址,一个是我们家里子网的IP地址:192.168.1.1/24,又称为LAN口IP地址。另一个是和运营商路由器组成的一个大的子网,我们称为WAN口IP:10.1.1.2/24。

所以我们的数据先到家用路由器,再到运营商路由器,接着再由运营商路由器转发,此时才算是真正进入到公网中。所以数据要进入公网,就要经过运营商路由器。

为什么交钱交给运营商?
路由器要有两个账号,第一个账号就是手机号,那么当你的报文经过家用路由器,转发给运营商路由器,那么运营商就可以根据你的手机号来判断你有没有交钱、欠费等情况,如果交钱了就不做拦截,给你转发到公网中,如果没交钱就拦截你的请求,不进行转发,你的报文也就无法进入公网了。另一个账号就是在你家里的子网,当你要连接家里的网络时可以看到网络的名称,并且要输入密码。

我们的报文必须经过运营商转发才能进入公网。
运营商可以因为你欠费不让你入公网,当然也可以因为你访问的地址非法,拦截你。

比如今天你要访问谷歌这个网站,运营商识别你要访问的是国外的网站,所以对你的进行拦截,不让你进入公网,所以你也就无法访问谷歌这个网站了。

而如果想要访问谷歌,就需要FQ,本质就是骗过运营商。


现在我们想向抖音服务器请求一个短视频,我们主机的IP地址为:192.168.1.201,抖音服务器IP地址为:122.77.241.3。所以首先填上源IP和目的IP地址,接着根据目的IP地址与子网掩码进行按位与操作,可以获取目标网络:122.77.241.0,而当前网络号为:192.168.1.0,我们主机当然不知道这个IP地址是哪台主机,但是可以肯定的是绝对不在当前子网中,因此就将它交给家用路由器。家用路由同样进行按位与,家用路由器同样不知道这个IP地址是谁,但是可以肯定的是绝对不在当前运营商路由器构建的大子网中,因此再交给运营商路由器。运营商路由器其实还可能继续向上叠加,构建成庞大的子网结构,不过我们当前图比较简单。运营商路由器收到报文,运营商路由器就将这个报文转到公网的抖音服务器上了。
那么现在抖音服务器就需要应答了,源IP地址就是:122.77.241.3,但是我们发现目的IP地址是192.168.1.201,这就出问题了,因为这是不可能给原来发送的主机应答的,因为内网IP是会被重复使用的,你压根不可能知道是拿一台主机。因此实际上在转发是下面这样的:


当你的主机将报文转发给家用路由器,家用路由器发现不在当前子网中,但是家用路由器的这个更大的子网已经和之前家里的子网不同了,所以源IP地址192.168.1.201就不能再出现在更大的子网中,所以家用路由器将srcip替换成所经过的路由器的WAN口IP,所以此时srcip变成了:10.1.1.2。接着转发给运营商出入口路由器,而内网IP是不能出现在公网中的,所以继续进行替换,srcip变成了:122.77.241.4,然后就进入公网转发给抖音服务器了。将来抖音服务器响应的时候,srcip就是:122.77.241.3,dstip就是:122.77.241.4,所以就将响应返回给曾经发送给我的出入口路由器。至于后续过程就需要到后面再来讲解。
我们把从内网到公网,源IP地址替换的技术称为:NAT技术(Network Address Translation)。

NAT技术缓解IP地址不足的问题?
因为它单独切分了一部分IP,只用它来做内网,这样IP地址就可以被重复利用。


2、全球网络:
IP地址这块大蛋糕首先被私有IP分了一部分出去,剩下的就是公网IP了。而剩下公网IP是以国家、组织、公司、学校等为单位进行申请的。

我们今天假设就以国家为单位进行申请,那么分配给美国的网络号就是1.0.0.0/8,分配给中国的就是6.0.0.0/8,而每个国家都要有国际路由器,比如美国的国际路由器IP为:1.0.0.1,中国的国际路由器IP为:6.0.0.1,其他国家如图所示。国家之间的路由器就组成了一个公网,当某个国家的国际路由器上线的时候,就需要通知所有其他国际路由器自己的IP地址、目标网络和子网掩码。因此中国的国际路由器里面就有以下几个条目信息,每个条目包含了目标网络、子网掩码、地区、下一跳(当然实际路由条目是没有包含地区的,此处包含地区是为了方便理解)。比如对于美国,目标网络就是1.0.0.0,子网掩码就是255.0.0.0,地区为美国,下一跳就是美国的国际路由器:1.0.0.1,对于其他国家同样如此。

那么中国分配的公网IP地址就是:6.0.0.0 ~ 6.255.255.255,我们国家还有33个省级行政单位,因此就需要继续往下划分,给每个省划分一部分公网IP地址:

由于前8位已经被国际路由器划分了,所以我们就需要向后划分,我们以次8位为例,划分给陕西的网络号为6.1.0.0/16,划分给浙江的网络号为6.5.0.0/16。当然还有其他省,这里就不画了,大家都懂的。这些省间也有省间路由器,对于陕西省间路由器IP就是6.1.0.1,子网掩码为255.255.0.0,对于浙江省间路由器IP就是6.5.0.1,子网掩码同样为255.255.0.0。然后把这些省间路由器和中国的国际路由器放在一个子网当中,当陕西上线了,就需要给其他省间路由器通告自己的IP地址、目标网络和子网掩码。所以浙江省间路由器条目就会有如下信息,比如目标网络6.1.0.0,子网掩码为255.255.0.0,地区为陕西,下一跳是6.1.0.1。那么对于其他省的省间路由器也是如此。

到达陕西之后,还可以继续往下划分,给每个市划分一部分公网IP,当前是16位我们可以再拿出4位进行划分,不过我们这里就不再做了。接下来就是当地运营商组建自己的局域网了:

陕西省组建了自己的省内局域网,其他省份也是如此,当然这个局域网的结构可能是非常多层的,我们这里就画两层。
现在如果陕西省内的一台主机192.168.1.201想要访问www.google网站,假设目标IP地址为1.2.3.4,并且假设不存在墙。那么当前主机首先会将目标IP地址与自己的子网掩码255.255.255.0进行按位与,然后跟自己所在的目标网络进行比较,发现不是当前所在的目标网络,该主机也不知道这个IP地址是谁,但是可以肯定的是绝对不在当前子网,所以转发给家用路由器。家用路由器和运营商的出入口路由器在同一个子网中,家用路由器拿着目标IP地址再与WAN口IP的子网掩码进行按位与操作,得到1.2.3.0,要去的1.2.3.0跟自己不在同一个网段,因此将源IP替换成当前路由器的WAN口IP,然后转发给运营商出入口路由器。然后运营商路由器再将该目标IP地址与子网掩码255.255.0.0进行按位与得到1.2.0.0,查找路由表,发现不是河南、不是云南、不是浙江,查完整个路由表条目都找不到,此时路由器判定不是去我们国家内部的,所以需要进行国际路由,因此在将该报文交给国际路由器。国际路由器收到之后也是一样,拿目标IP和子网掩码进行按位与得到1.0.0.0,发现要去的就是美国,所以这时候就直接干到美国去了。

陕西、河南、云南、浙江省间路由器都会配置有缺省路由,它们得到缺省路由就是中国的国际路由器。而家庭中的主机配置的缺省路由就是家用路由器。家用路由器配置的缺省路由就是运营商路由器。


如果在路由表条目中查不到,就转发到缺省路由。


那么到了美国之后,美国需要给我们应答,这时候src就是1.2.3.4,dst就是6.1.0.1,美国的国际路由器将目标IP地址跟自己的子网掩码255.0.0.0进行按位与得到6.0.0.0,发现要去的目标网络就是中国,所以就交给了中国的国际路由器,这时候就到中国了。然后中国的国际路由器拿着目标IP地址查路由表,根据第一个条目子网掩码按位与得到6.0.0.0,比对目标网络1.0.0.0不匹配,所以继续往下。然后到了省内地区的,子网掩码就由8收敛到了16位,然后按位与得到6.1.0.0,发现要去的地区就是陕西,所以就交给了陕西省间路由器,这时候就到了陕西省了,然后就是内网转发的过程。


5、路由


当数据从主机A发送给主机B,要交给路由器A、路由器B、路由器C、路由器D,然后最后到主机B。从主机A到路由器A就是一个子网的转发,从路由器A到路由器B就是另一个子网转发,所以网络通信本质是一个子网到另一个子网。
当今天你在进行路由转发的时候,查找路由表无非就是三种情况:
1、比如上面讲的访问www.google,当你的报文到达国际路由器,查路由表发现你下一跳应该到达美国。
2、当你查完所有路由表条目都匹配不成功,那么就会交给默认路由。所以路由器是要配置默认路由的!
3、你当前已经到了目标网络了,接下来就是局域网通信的过程了。

主机和路由器在自己的网络层都配置了自己的路由表信息。

如图:Destination表示目标网络,Gateway表示下一跳的主机,Genmask表示子网掩码,Iface表示通过哪个接口转发。Flags中的U标志表示此条目有效(可以禁用某些条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发。

转发过程示例1:假设目标主机为:192.168.56.3,首先跟第一行的子网掩码按位与得到192.168.56.0,而第一行目标网络为192.168.10.0,所以不匹配继续往下。第二行按位与后得到192.168.56.0,跟目标网络相同,所以通过eth1接口发送出去。
转发过程示例2:假设目标主机为:202.10.1.2,根据前三行的子网掩码按位与并于目标网络比对,发现都不匹配,因此最后走的是default缺省路由,通过eth0接口发送出去。


6、IP分片和组装


IP报文转发的过程本质就是在各个子网间进行转发。
IP主要解决的核心问题是路径选择。而路径选择就是在淘汰其他子网。
路由转发过程分为两阶段:1、寻找目标网络,根据目标网络进行路由。2、在内网进行转发。

而关于IP报头中的16位标识、3位标志、13位片偏移我们还没聊过,下面就来聊这三个字段,首先我们需要跟TCP联动一下。

TCP的滑动窗口是由对端接收窗口和拥塞窗口共同决定的,但是为什么不把滑动窗口中的数据打包成一个大报文直接发送,而是分成了一个一个数据段发送?首先如果IP报文太长了,IP报文就需要进行分片。
数据链路层规定:单次发送数据帧的有效载荷长度不能超过MTU(1500)


所以如果网络层数据太长了,那么网络层就需要进行分片。分片是由网络层进行的,那么将来进行组装的时候就由对方的网络层进行组装。(谁污染谁治理)。
自己的网络层和对方的网络层进行分片和组装,因此就有了上方的IP报头中的那三个字段。

分片好还是不好?
1、分片组装的细节,上层传输层不关心。
传输层给网络层10000字节的有效载荷,分片是由网络层进行的,将来对方的网络层要对这些分片进行组装合并成10000字节,然后交给上层传输层,网络层向上交付给传输层必须是10000字节。因此传输层在这个过程中不关心。
2、本来10000字节直接发送就是一个报文,分片后如:10*1000,那就是10个报文。将来任意一个报文丢包,就是不完整的,网络层组装失败而传输层压根就不关心,所以任意一个丢了就直接认为是丢包了。
3、分片之后,丢包的概率增加了。因此分片不能作为网络发送的主流!那么为了不分片,就需要传输层不要发送太大的报文段!

所以滑动窗口中的数据不直接打包成一个大报文是为了减少分片。


IP分片了如何进行组装?
IP分片对传输层是透明的,这意味着传输层无需关心数据是否被分片以及如何重新组装。

16位标识(id):唯一的标识主机发送的报文。如果IP报文在数据链路层被分片了,那么每一个片里面的这个id都是相同的。

3位标志字段:第一位保留(保留的意思是现在不用,但是还没想好说不定以后要用到)。第二位置为1表示禁止分片,这时候如果报文长度超过MTU,IP模块就会丢弃报文。第三位表示"更多分片",如果分片了的话,最后一个分片置为0,其他是1。类似于一个结束标记。

13位分片偏移(framegament offset):是分片相对于原始IP报文开始处的偏移。其实就是表示当前分片在原报文中处在哪个位置。实际偏移的字节数是这个值除以8得到的。因此,除了最后一个报文之外(之前如果都是8的整数倍,最后一片的偏移量也一定是8的整数倍),其他报文的长度必须是8的整数倍(否则报文就不连续了)。

1、接收方如何得知自己收到的报文分片了?
下面我们分别分析三种情况下的16位标识、3位标志、13位片偏移的值
收到第一个分片:16位标识,001,0
收到中间分片:16位标识,001,不为0
收到结尾分片:16位标识,000,不为0
而当我们没有分片,这是一个完整的报文:16位标识,000,0。只有这一种情况。

因此,如果3位标志 == 000 并且 片偏移 == 0 说明没有分片,否则就是分片了。
如果3位标志 != 000 或者 片偏移 != 0 说明分片了。

2、接收方如何得知自己收到的分片收全了?
1、根据16位标识,将分片放在一起。
2、按照片偏移进行升序排序。
3、情况说明
3.1、第一片丢失:排完序之后,第一片的片偏移不为0,说明第一片丢失了。
3.2、结尾丢失:整个报文中只有最后一个分片的更多分片标志位为0,升序排序之后找到最后一片,判断其分片标志位是否为0,为0标识收到了,不为0表示结尾丢失。
3.3、中间丢失:报文的偏移量=上一个报文的偏移量+上一个报文的长度,所以可以通过当前报文的偏移量+当前报文大小是否等于下一个报文的偏移量判断,如果相等说明中间没有丢失,如果不相等说明中间报文丢失了。

3、接收方如何组合形成完整的报文?
根据前面两点自然而然可以得出这个问题的答案。直接排升序,可以先判断第一片和最后一片是否丢失,然后从第一片开始,根据当前片偏移+当前这一片的大小判断下一片的偏移量是否相等,相等就可以拼接起来,否则就是缺失。


IP如何分片?

细节1:分片是对IP报文的有效载荷进行分片的。
细节2:片偏移是数据相对于原始IP报文有效载荷开始的偏移量。
细节3:片偏移具体的数字必须是8的整数倍。

比如这一片的片偏移为1480,那么在IP报头中的13位片偏移就是1480/8=185。为什么呢?
13位片偏移能表示的范围是:[0, 2^13],但是IP报头有16位总长度,所以IP报文的长度范围是:[0, 2^16],因此为了让13位片偏移能表示2^16的数据,需要让13位片偏移乘以2^3。因此将来发送发分片后填的时候需要除以8,接收方接收进行组装需要乘以8。

细节4:分片之后,每一片就是一个IP报文,每一片都要包含IP报头。

如图:我们假设有3000字节的数据,分片首先每一片都是需要包含IP报头的,因此一片的有效载荷最大就是1500-20=1480,第一片就是前1480字节的数据加上IP报头。其中IP报头中的16位标识为6666(随便给的),更多分片标志位为1表示后面还有分片,片偏移为0。
然后第二片就是从1480~2960的数据,加上IP报头。IP报头的16位标识相同为6666,更多分片为1标识还有分片,片偏移应该是1480/8=185。
最后一片只有40个字节的数据加上IP报头,其中16位标识同样是6666,更多分片为0表示这是最后一个分片了,片偏移为2960/8=370。至此,我们就完成了一个IP报文的分片过程。

我们刚刚谈的是在发送方和接收方进行分片和组装,但是分片和组装还可能在网络中进行。因为中间经过的路由器可能是老式路由器,如果配置的MTU为500,就会对分片再做分片。第一次分片的规则就如我们上面所说,再次分片就把16位标识和更多分片拷过来,然后根据不同的片偏移进行更新,比如对上图中的第二片继续分片,那么分片后的片偏移就是185+xxx…