文章目录
- [1. 网络层做了什么事](#1. 网络层做了什么事)
- [2. IP协议的简介](#2. IP协议的简介)
- [3. IP协议格式](#3. IP协议格式)
- [4. 分片与组装](#4. 分片与组装)
- [5. 网段划分](#5. 网段划分)
- [6. 特殊的IP地址](#6. 特殊的IP地址)
- [7. IP地址的数量限制](#7. IP地址的数量限制)
- [8. 私网IP地址和公网IP地址](#8. 私网IP地址和公网IP地址)
- [9. 路由](#9. 路由)
1. 网络层做了什么事
保证数据可靠地从一台主机到另一台主机
当双方在进行基于TCP的网络通信时,要保证将数据可靠地从一台主机送到另一台主机,前提是发送方要有将数据送到对方主机的能力。
- 发送方有将数据发送给对方主机的能力,并不意味着发送方每次发送的数据都能够成功地发送到对方,但如果发送方连数据发送给对方的能力都没有,那发送方肯定不可能将数据发送给对方。
- 一旦发送方有了将数据发送给对方的能力,就算发送方某次发送的数据没有成功发送给对方,此时上层TCP由于没有收到对方数据的应答,就会要求进行数据重发,直到数据成功发送给对方即可。
也就是说,在网络层有能力将数据发送到对方主机的情况下,虽然网络层不能保证每次都能将数据成功发送过去,但是在TCP可靠性策略的保证下,最终网络层一定能够将数据传送过去。
说明一下:
- 网络层解决的问题,将数据从一台主机发送到另一台主机,因此网络层解决的是主机到主机的问题。
- 传输层从上层进程拿到数据之后,该数据贯穿网络协议栈进行封装和解包,最终到达对方的传输层,从而交付给上层进程,所以传输层解决的是进程到进程的问题。
路径选择
数据进行网络传输一般都是跨网络的,而路由器就是连接多个网络的硬件设备,因此数据在进行跨网络传输时一定要经过多个路由器。
数据路由就像我们出行一样,当确定了要到达的目标主机之后,就要寻找最短的路径到达该目的地。
- 目的地的确定是非常重要的,因为目的地直接决定了数据路由时的路径选择。
- 只有数据经过了较为正确的目的选择,最终才可能慢慢趋近于目标网络或者目标主机。
确定数据路由的目的地之后,数据就可以在网络中进行路由了,但数据在路由时无法自行进行路径选择,因为这个数据本省是"不认识路"的,因此数据在路由的过程中需要不断"找人问路",而这里所谓的"路人"就是网络中的一台台路由器。
网络当中的路由器是"认识路的",它们会将自己的"认路经验"都记录到路由表当中,因此路由器可以通过查路由表的方式去找到特定点的最短路径。因此数据在路由时,会不断通过路由器来进行路径选择,以此来一步步靠近目标网络或者目标主机。
认识一下主机和路由器
- 主机:配有IP地址,但是不进行路由控制的设备。但实际现在几乎不存在不进行路由控制的设备了,连笔记本都会进行路由控制。
- 路由器:既配有IP地址,又能进行路由控制。实际现在主流的路由器已经不仅仅具有路由的功能了,它甚至具备某些应用层的功能。
- 节点:主机和路由器的统称。
2. IP协议的简介
IP是(Internet Protocol,网络互联协议的缩写),是TCP/IP体系中的网络层协议。设计IP的目的是提高网络的可扩展性:
- 一方面解决互联网问题,实现大规模、异构网络的互联互通。
- 另外一方面是分割顶层网络应用于底层网络技术之间的耦合关系,以利于两者的独立发展。
因为目前IP协议主流的版本有IPV4和IPV6,但是目前IPV6不够普及,并且泛用性小,所以这篇文章着重简介IPV6。
3. IP协议格式
- 4位版本号(version):指定IP协议的版本(IPv4/IPv6),对于IPv4来说,就是4.
- 4位首部长度(header length):表示IP报头的长度,以4字节为单位。
- 8位首部长度(Type Of Service):3位优先权字段(已经弃用),4位TOS字段和1位保留字段(必须置为0)。4位TOS分别表示:最小延时、最大吞吐量、最高可靠性、最小成本。这四者是相互冲突的,只能选择一个。比如对于ssh/telnet这样的程序,最小延时比较重要,而对于ftp(文件传输协议)这样的程序,最大吞吐量比较重要。
- 16位总长度(total length):IP报文(IP报文+有效载荷)的总长度,用于将各个IP报文进行分离。
- 16位标识(id):唯一的标识主机发送的报文,如果数据在IP层进行了分片,那么每一个分片对应的id都是相同的。
- 3位标志字段:第一位保留,标识暂时没有规定该字段的意义。第二位标识禁止切片,标识如果报文长度超过MTU,IP模块就会丢弃该报文。第三位表示"更多分片",如果报文没有进行分片,则该字段置为0,如果报文进行了分片,则除了最后一个分片报文设置为0以外,其余分片报文均设置为1。
- 13位片偏移(framegament offset):分片相对于原始数据开始处的偏移,表示当前分片在原数据中的偏移位置,实际偏移字节数就是这个值 * 8 得到的。因此除了最后一个报文之外,其他报文的长度必须是8的整数倍,否则报文就不连续了。
- 8位生存时间(Time To Live,TTL):数据包到达目的地的最大报文跳数,一般是64,每经过一个路由,TTL减去1,一直减到0还没有到达,那么就会丢弃,这个字段主要是防止出现路由循环。
- 8位协议:表示上层协议的类型。
- 16位首部检验和:使用CRC进行校验,来鉴别数据报的首部是否损坏,但不检验数据部分。
- 32位源IP地址和32位目的IP地址:表示发送端和接收端所对应的IP地址。
- 选项字段:不定长,最多40字节。
IP报头在内核当中本质就是一个位段类型,给数据封装IP报头时,实际上就是用该位段类型定义了一个变量,然后填充IP报头当中的各个属性字段,最后将这个IP报头拷贝到数据的首部,至此便完成了IP报头的封装。
如何将IP报头与有效载荷分离?
IP分离报头与有效载荷的方法与TCP是一模一样的,当IP从底层获取到一个报文之后,虽然IP不知道报文的具体长度,但IP报文的前20个字节是IP的基本报头,并且这20字节当中涵盖4位首部长度。
因此IP是这样分离报头与有效载荷的:
- 当IP从底层获取到一个报文后,首先读取报文的前20个字节,并从中提取出4位的首部长度,通过4位的首部长度便知道了IP报头的大小size。
- 如果size的值大于20字节,那么要继续从报文中读取 size - 20 字节,这一部分就是IP报头当中的选项字段。
- 读取完IP的基本报头和选项字段后,剩下的就是有效载荷了。
IP就是通过这种"定长报头+自描述字段"的方式进行报头与有效载荷分离的。
IP如何得知要将有效载荷交付给上层的哪一个协议?
在IP报头中有一个字段叫做8位协议,该字段表示的就是上层协议的类型,IP就是根据该字段判断应该将分离出来的有效载荷交付给上层的哪一个协议的。
理解socket编程
- 在进行socket编程的时候,当一端想要发送数据给另一端时,必须要指明对端的IP地址和端口号,也就是发送数据的目的IP地址和端口号。
- 其中这里的IP地址就是给网络层的IP使用的,用于数据在网络中的路由转发,而这里的端口号就是给传输层的TCP或UDP使用的,用于指明数据应该交给上层的哪一个进程。
- 发送数据时我们不需要指明发送数据的源IP地址和端口号,因为传输层和网络层都是在操作系统内核当中实现的,数据在进行封装时操作系统会自行填充上对应的源IP地址和源端口号。
8位生存空间
报文在网络传输过程中,可能因为某些原因导致报文无法到达对端主机,比如报文在路由时出现了路由环路的问题,或者目标主机已经离线,此时这个报文就成了一个废弃的游离报文。
为了避免网络中出现大量的游离报文,在IP的报头中会有一个字段,叫做8位生存空间(Time To Live,TTL)。8位生存空间代表的是报文到达目的地的最大报文跳数,每当报文经过一次路由,这里的生存空间就会减一,当生存空间减为0时该报文就会被自动丢弃,此时这个报文就会在网络中消散。
4. 分片与组装
数据链路层解决的问题
IP能够将数据跨网络从一台主机送到另一台主机,而数据在进行跨网络传送时,需要经过一个个的路由器进行路由转发,最终才能到达目标主机。
比如要将数据从主机B跨网络传送到主机C,那么主机B需要先将数据交给路由器F,路由器F再将数据交给路由器G,如此下去,最终由路由器D交给主机C。
因此IP进行跨网络传送的前提是,先将数据从一个节点传送到和自己相连的下一个节点,这个问题实际就是由IP之下的数据链路层解决的,其中数据链路层最典型的代表协议就是MAC帧。
而两个节点直接相连就意味着这两个节点是在同一个局域网中的,因此要讨论两个相邻节点的数据传送时,实际讨论的就是局域网通信的问题。
最大传输单元MTU
MAC帧作为数据链路层的协议,它会将IP传下来的数据封装成数据帧,然后发送到网络当中。但MAC帧携带的有效载荷的最大长度是有限度的,也就是说IP交给MAC帧的报文不能超过某个值,这个值叫做最大传输单元(Maximum Transmission Unit,MTU),这个值的大小一般就是1500字节。
在Linux使用ifconfig命令可以查看对应的MTU。
由于MAC帧无法发送大于1500字节的数据,因此IP层向下交付的数据长度不能超过1500字节,这里所说的数据包括IP的报头和IP的有效载荷。
分片与组装
如果IP层要传送的数据超过1500字节,那么就需要先在IP层对该数据进行分片,然后将分片后的数据交给下次MAC帧进行发送。
如果发送数据时在IP层进行了分片,那么当这些分片数据到达对端主机的IP层后就需要先进行组装,然后再组装好的数据交付给上层传输层。
- 数据的分片不是经常要做的,实际在网络通信过程中不分片才是常态,因为数据分片会存在一些潜在的问题,比如分片可能会增加丢包的概率。
- 数据的分片和组装发生在IP层,不仅源端主机可能会对数据进行分片,数据在路由过程中的路由器也可能对数据进行分片。因为不同网络的MTU是不一样的,如果传输路径上的某个网络的MTU比源端网络的MTU小,那么路由器就可能对IP数据报进行再次分片。
- 分片数据的组装只会发生在目的端的IP层。
- 在分片的数据中,每一个分片在IP层都会被添加对应的IP报头,而传输层添加的报头只会出现在第一个分片中,因此网络中传输的数据包可能没有传输层的报头。
为什么不建议进行分片?
虽然传输层并不关心IP层的分片问题,但分片对于传输层也是有影响的。
- 如果一个数据在网络传输过程中没有经过分片,那么只要接收端收到了这一个报文,我们就可以认为该数据被对方可靠地收到了。
- 而如果一个数据在网络传输过程中进行了分片,那么只有当接收端收到了全部的分片报文并将其成功组装起来,这时我们才认为该数据被对方可靠地收到了。但如果众多的分片报文当中有一个报文出现了丢包,就会导致接收端无法将报文成功组装起来,这时接收端会将收到的分片报文全部丢弃,此时传输层TCP会因为收不到对方应答而进行超时重传。
- 假设在网络传输时丢包的概率是万分之一,如果将数据拆分为一百分进行发送,那么此时丢包的概率就上升到了百分之一。因为只要有一个分片报文丢包了也就等同了这个报文整体丢失了,因此分片会增加传输层重传数据的概率。
也就是说,只要分片报文中某一个出现了丢包,就要对整体进行重传,因此数据在发送时不建议进行分片。
如何尽可能避免分片?
实际数据分片的根本原因在于传输层一次向下交付的数据太多了,导致IP无法直接将整体数据交付给MAC帧,如果传输层控制好一层交付的数据不要太大,那么也就不会出现数据分片的情况。
- 因此TCP作为传输控制协议,它需要控制一次向下交付的数据不超过某一阈值,这个阈值就叫做MSS(Maximum Segment Size,最大报文段长度)。
- 通信双方在建立TCP连接时,除了需要协商自身窗口大小等概念之外,还会协商后续通信时每一个报文段所能承载的最大报文段MSS。
5. 网段划分
IP地址的构成
IP地址由网络号和主机号两部分构成:
- 网络号:保证相互连接的两个网段具有不同的标识。
- 主机号:同一网段内,主机之间具有相同的网络号,但是主机号是不同的。
IPv4总共有32位,可以在IP地址的后面加上一个 / ,并在 / 后面加上一个数字,这就表示从头到第几位是属于网络标识。
例如,下图中路由器连接了两个网段。对于网络标识来说,同一网段内主机的网络标识是相同的,不同网段内主机的网络标识是不同的。而对于主机标识来说,同一网段内的主机标识是不同的,而不同网段的主机标识是可以相同的。
DHCP协议
实际手动管理IP地址是一个非常麻烦的事情,当子网中新增主机时需要给其分配一个IP地址,当子网中有主机断开网络时又要将其IP地址进行回收。
- 因此对于IP地址的分配和回收一般不会手动进行,而是采用DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)技术。
- DHCP通常被用于大型的局域网环境中,其主要作用就是集中地址管理、分配IP地址,使网络中的主机获得IP地址、Gateway地址、DNS服务器地址等信息,并能够提升地址的利用率。
- DHCP是一个基于UDP的应用层协议,一般的路由器都带有DHCP功能,因此路由器也可以看作一个DHCP服务器。
当我们连接WiFi时需要输入密码,本质就是因为路由器需要验证你的账号和密码,如果验证通过,那么路由器就会给你分配一个IP地址,然后你就可以基于这个IP地址进行上网了。
先找目标网络,再找目标主机
当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
判断一个IP地址属于哪一类时,可以从高到低位遍历,看第几位出现0,从而得知其属于哪一类。
子网划分
但随着网络的飞速发展,这种划分方案的局限性也很快显现出来了。
- 在一些学习、公司、实验室等组织中,它们大多使用的是B类地址,B类地址的主机号占16个比特位,因此理论上一个B类网络当中允许有65536台主机。
- 但实际网络架设中,一般不会存在一个局域网中有这么多主机的情况,也就意味着大量的IP地址实际都被浪费掉了。
为了避免这种情况,于是又提出了新的划分方案,称为CIDR。
- 在原有的五类网络的基础上继续进行子网划分,这也就意味着需要借用主机号当中的若干位来充当网络号,此时为了区分IP地址中的网络号和主机号,于是引入了子网掩码的概念。
- 每一个子网都有自己的子网掩码,子网掩码实际就是一个32位的正整数,通常用一串 0 来结尾。
- 将IP地址与当前网络的子网掩码进行"按位与"操作,就能够得到当前网络所在的网络号。
此时一个网络就被更细粒度地划分为一个个更小的子网,通过进行不断的子网划分,子网中IP地址对应的主机号就越来越短,因此子网当中可用IP地址的个数也就越来越少,这也就避免了IP地址被大量浪费的情况。
- 比如在某一子网中将IP地址的前24位作为网络号,那么该网络对应的子网掩码的32个比特位中的前24位就为1,剩下的8个比特位为0,将其用点分十进制表示就是255.255.255.0。
- 假设该子网当中有一台主机对应的IP地址是192.168.128.10,那么将这个IP地址与该网络当中的子网掩码进行按位与操作得到的就是192.168.128.0,这就是子网对应的网络号了。
- 实际在用于子网掩码与子网当中主机的IP地址进行"按位与"操作时,本质就是保留了主机IP地址中前24个比特位的原貌,将剩下的8个比特位的值清0了而已,也就是将主机号清0了,所以按位与之后的结果就是该网络对应的网络号。
需要注意的是,子网划分并不是只能进行一次,我们可以在划分出来的子网的基础上进行子网划分。
因此一个数据在路由的时候,随着数据不断路由进入更小的子网,其网络号的位数是在不断变化的,准确来说其网络号的位数是在不断增加的,这也就意味着IP地址当中的主机号的位数在不断减少。最终当数据由到达目标主机所在网络时,就可以在该网络当中找到对应的目标主机并将数据交给该主机,此时该数据的路由也结束了。
6. 特殊的IP地址
并不是所有的IP地址都可以作为主机的IP地址,有些IP地址是具有特殊用途的。
- 将IP地址中的主机地址全部设为0,就成为了网络号,代表这个局域网。
- 将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包。
- 127.*的IP地址用于本地环回测试,通常是127.0.0.1。
也就是说,IP地址中主机号全为0的是当前局域网的网络号,主机号全为1的代表的是广播地址,这两个IP地址都是不能作为主机的IP地址的。因此在某个局域网中最多能存在的主机个数是2^主机号位数^ -2。
本地环回原理
本地环回会将数据贯穿网络协议栈,但最终不会将数发送到网络当中,相当于本地环回时不会将数据写到网卡上面。
本地环回的目的就是将数据自定向下贯穿协议栈,进行一次数据封装的过程,然后再自底向上贯穿协议栈,进行一次数据解包的过程,通常用于测试本地的网络功能是否正常。
本地环回的基本原理:
- 当数据到大IP层需要继续向下交付时,如果是环回程序,那么IP输出函数会将数据放入到IP输入队列中,然后由IP输入函数读取上去。
- 而IP输入函数将数据读取上去的本应该是数据链路层向上交付的数据,因此该数据后续就会被当做从网络中读取的数据来看待,各层协议会一次对该数据进行解包和分用。
- 如果不是本地环回的话,那么接下来就会判断该数据对应的目的IP地址是否为广播多多播地址,或者目的IP地址是否与本主机的IP地址相同,如果是则也会将数据放入到IP读入队列当中,等待IP读入函数读取。
7. IP地址的数量限制
IP地址数量不足的问题
我们知道,IP地址(IPv4)是一个4字节32位的正整数,因此一共有2^32^个IP地址,也就是将近43亿个IP地址。但TCP/IP协议规定,每个主机都需要有一个IP地址。
- 现在全世界人品已经有70多亿了,就算有一半的人没有智能手机,算下来也有30亿台只能手机需要IP地址。
- 随着科技的发展,我们使用的电脑、智能手表、智能冰箱、智能洗衣机等设备如果入网也是需要IP地址的。
- 另外,IP地址并不是按照主机台数太进行配置的,因此一个主机可能需要多个IP地址,更别谈还有很多组网的路由设备也需要IP地址,以及一些特殊的IP地址不能使用的问题。
所以43亿个IP地址其实是不够用的,因此才提出来CIDR的方案对已经划分好的五类ID地址进行子网划分,其目的就是减少IP地址的浪费。
CIDR虽然在一定程度上缓解了IP地址不够用的问题,因为CIDR提高了IP地址的利用率,减少了浪费,但IP地址绝对上限并没有增加。
如何解决IP地址不足的问题?
- 动态分配IP地址:只给接入网络的设备分配IP地址,因此同一个MAC地址的设备,每次接入互联网时,得到的IP地址不一定是相同的,避免了IP地址强绑定于某一台设备的情况。
- NAT技术:能够让不同局域网当中同时存在两个相同的IP地址,NAT技术不仅能够解决IP地址不足的问题,而且还能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。
- IPv6:IPv6使用16字节128位来表示一个IP地址,能够大大缓解IP地址不足的问题。但IPv6并不是IPv4的简单升级版,它们是不相干的两种协议,彼此并不兼容,因此目前IPv6还没有普及。
8. 私网IP地址和公网IP地址
如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连接到Internet上,理论上使用任意的IP地址都可以,但是RFC 1918规定了用于组建局域网的私有IP地址。
- 10.*,前8位是网络号,共有16777216个地址。
- 172.16.* 到 172.32.*,前12位是网络号,共1048576个地址。
- 192.168.*,前16位是网络号,共65536个地址。
包含在这个范围中的,都称为私网IP,其余的为公网IP(或全局IP)。
我们连接云服务器时,使用的地址就是服务器的公网IP地址。
我们可以通过ifconfig命令查看我们这台机器的私网IP,其中网络接口lo(loop)代表的是本地环回,而eth0代表的是我们这台机器的网络接口。
我们为什么要给运营商交钱?
我们享受的是互联网公司为我们提供的服务,为什么要向运营商交钱呢?
- 实际网络通信的基础设施都是运营商搭建的,我们访问服务器的数据并不是直接发送到了对应的服务器,而是需要经过运营商建设的各种基站以及各种路由器,最终数据才能到达对应的服务器。
- 因为运营商为我们提供了通信的基础设施,所以我们交网费实际就相当于购买入网许可一样。
- 没有运营商提供的这些基础设施,就不会诞生所有的互联网公司,因为互联网公司是运营在网络基础设施之上的。
也就是说,用户上网的数据首先必须经过运营商的相关网络设备,然后才能发送到互联网公司对应的服务器。因此所谓的网段划分、子网划分等工作实际都是运营商做的。
数据是如何发送到服务器的?
路由器是连接两个或多个网络的硬件设备,在路由器上有两种网络接口,分别是LAN口和WAN口。
路由器是连接两个或多个网络的硬件设备,在路由器上有两种网络接口,分别是LAN口和WAN口:
- LAN口(Local Area Network):表示本地连接网络的端口,主要与家庭网络中的交换机、集线器或PC相连。
- WAN(Wide Area Network):表示连接广域网的端口,一般指互联网。
我们将LAN口的IP地址叫做LAN口IP,也叫做子网IP,将WAN口的IP叫做WAN口IP,也叫做公网IP。
- 不同路由器,子网IP其实都是一样的(通常都是192.168.1.1),子网内的主机IP地址不能重复,但是子网之间的IP地址就可以重复了。
- 每一个家用路由器,其实又作为运营商路由器子网中的一个节点,这样运营商路由器可能会有很多级,最外层的运营商路由器的WAN口IP就是一个公网IP了。
- 如果系统我们自己实现的服务器程序,能够在公网上被访问到,就需要把服务部署在一台具有外网IP的服务器上,这样的服务器可以在阿里云或者腾讯云购买。
由于死亡IP不能出现在公网当中,因此子网内主机在和外网进行通信时,路由器会不断将数据包IP首部中的IP地址转换成路由器的WAN口IP,这样逐级替换,最终数据包中的源IP会成为一个公网IP,这种技术被称为NAT技术(Network Address Translation,网络地址转换)。
为什么私网IP不能出现在公网当中?
- 不同的局域网中的主机的IP地址可能是相同的,所以私网IP无法唯一标识一台主机,因此不能让私网IP出现在公网上,因为IP地址要能唯一标识公网上的一台主机。
- 但由于IP地址不足的原因,我们不能让主机直接使用公网IP而让主机使用IP,因为私网IP可以重复也就意味着我们可以在不同的局域网中使用相同的IP,缓解的IP的不足问题。
- 此外,我们不能直接使用公网IP还有一个原因就是,我们的数据包必须要经过经营商的路由器,如果我们发送的数据直接到了公网,那也就意味着我们再也不用交网费了,这是不现实的。
两个局域网中的主机不能不跨公网进行通信
- 两个局域网中的主机是不能不跨公网进行通信的,因为一个主机要将数据发送给另一台主机的前提是得知另一台主机的IP地址。
- 即便现在这个主机知道了另一台主机的IP地址,但是有可能这两台主机的IP地址是一样的,因为它们的IP地址都是私网IP地址。
- 当这一台主机发送数据时将目的IP地址填成和自己相同的IP地址,操作系统就会认为这个数据是要发送给自己的,而不会向外进行发送了。
所以数据如果要从一个局域网发送到另一个局域网,如果不经过公网基本上是不可能的,当我们和别人聊天的时候,也不是直接将数据从一个局域网直接发送到了另一个局域网,而是先将数据通过公网发送到服务器,服务器再通过公网将数据转发到另一个局域网中。
但也存在一些技术能够使数据包在发送过程中不进行公网IP的替换,而将数据正确发送到目标主机,这种技术叫做内网穿透,也叫做NAT穿透。
9. 路由
数据"问路"的过程
数据在路由的过程中,实际就是一跳一跳"问路"的过程,所谓"一跳"就是数据链路层的一个区间,具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间。
IP数据包的传输过程中会遇到很多路由器,这些路由器会帮助数据包进行路由转发,每当数据包遇到一个路由器之后,对应路由器都会查看该数据的目的IP地址,并告知该数据下一跳应该往哪跳。
路由器的查找结果可能有以下三种:
- 路由器经过路由表查询后,得知该数据下一跳应该跳到哪一个子网。
- 路由器经过路由表查询后,发现没有匹配的子网,此时路由器会将该数据转发给默认路由。
- 路由器经过路由表查询后,得知该数据的目标网络就是当前所在的网络,此时路由器就会将该数据转给当前网络中对应的主机。
路由表的查询
每个路由器内部都会维护一个路由表,我们可以通过route命令查看云服务器上的路由表。
- Destination:表示的是目的网络地址。
- Gateway:表示的是下一跳地址。
- Genmask:表示的是子网掩码。
- Flags:U表示的是此条目有效(可以禁用某些条目),G表的是词条此条目的下一跳地址是某个路由器的地址,没有G标志的条目标识目的网络地址是与本机接口直接相连的网络,不必经过路由器转发。
- Iface:表示的是发送接口。
当IP数据包到达路由器时,路由器就会用该数据的目的IP地址,一次与路由表中的子网掩码Genmask 进行"按位与"操作,然后将结果与子网掩码对应的目的网络地址Destination 进行比对,如果匹配则说明该数据包下一跳就应该跳去这个子网,此时就会将数据包通过对应的发送接口Iface发出。
如果将该数据包的目的IP地址与子网掩码进行按位与操作之后,没有找到匹配的目的网络地址,此时路由器就会将这个数据包发送到默认路由,也就是路由表中目标网络地址中的default ,可以看到默认路由对应的flags 是UG,实际就是将该数据转发给另一台路由器,让该数据在另一台路由器继续进行路由。
数据包不断经过路由器路由后,最终就能到达目标主机所在的目标网络,此时就不再根据该数据包目的IP地址当中的网络号进行路由了,而是根据目的IP地址当中的主机号进行路由,最终根据数据包对应的主机号就能将数据发送到目标主机了。
路由表生成算法
路由可分为静态路由和动态路由:
- 静态路由:是指由网络管路员手工配置路由消息。
- 动态路由:是指路由器能够通过算法自动建立自己的路由器,并且能够根据实际情况进行判断。
路由表生成算法:距离向量算法、LS算法、Dijkstra算法等。