IP协议

  • 一、网络层的作用
  • 二、IP协议格式
  • 三、分片与组装
    • 1、最大传输单元 MTU
    • 2、分片和组装的宏观过程
    • 3、分片的详细过程
    • 4、组装的详细过程
    • 5、分片的其他相关问题
  • 四、网段划分
    • 1、IP地址的构成
    • 2、DHCP协议
    • 3、IP 地址的分类
      • Ⅰ、无分类地址 CIDR
      • Ⅱ、特殊的IP地址
    • 4、公有IP与私有IP
      • Ⅰ、IP地址的数量限制
      • Ⅱ、私有IP
      • Ⅲ、公有IP
  • 五、网络结构
    • 1、公网网络结构
    • 2、私网网络结构
  • 六、路由
    • 1、路由过程的宏观介绍
    • 2、路由表生成算法(了解)
    • 3、一个简单的通信流程

IP协议指网际互连协议,Internet Protocol的缩写,是TCP/IP体系中的网络层协议。

IP是一种 「不可靠」的 「端到端」的数据包 「传输服务」,主要实现两个功能:

  • 数据传输
  • 数据分片。

一、网络层的作用

TCP作为传输层控制协议,其保证的是数据传输的可靠性和传输效率,但TCP提供的仅仅是数据传输的策略,而真正负责数据在网络中传输的则传输层之下的网络层和数据链路层。

而网络层要解决的问题就是:将数据跨网路从一台主机送到另一台主机,也就是数据的路由

虽然网络层有能力将数据送到对方主机,但是网络层不能保证每次都能将数据成功送到对方主机,于是有了TCP提供的可靠性策略,最终网络层就一定能够将数据可靠的发送到对方主机。

网络中的一些基本概念

  • 主机: 配有IP地址的设备。
  • 路由器: 配有多个IP地址, 又能进行路由控制的设备;
  • 节点: 主机和路由器的统称。

网络中的路径选择

数据进行的网络传输一般都是跨网络的,而路由器就是连接多个网络的硬件设备,因此数据在进行跨网络传输时一定需要经过多个路由器。

在网络中我们使用IP地址来定位全球中的某一台主机,我们定位了一台主机以后,就需要在网络中传输时需要不断的查询路由表,不断的接近目标主机。

二、IP协议格式

  • 4位版本号(version):指定IP协议的版本,对于IPv4来说,就是4,此外IPv4与IPv6是不兼容的,这里的4位版本号不适用于IPv6。

  • 4位首部长度(header length):表示IP报头的长度,以4字节为单位,所以如果没有选项,这里应该是 010101010101

  • 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位标志字段

    • 第一位保留,表示暂时没有规定该字段的意义。

    • 第二位表示禁止分片,为1表示开启禁止分片,如果报文长度超过MTU,IP模块就会丢弃该报文。

    • 第三位表示更多分片,如果报文没有进行分片,则该字段设置为0,如果报文进行了分片,则除了最后一个分片报文设置为0以外,其余分片报文均设置为1。

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

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

  • 8位协议:表示上层协议的类型,例如TCP协议,UDP协议。

  • 16位首部检验和:使用CRC进行校验,来鉴别数据报的首部是否损坏,但不检验数据部分。

  • 32位源IP地址和32位目的IP地址:表示发送端和接收端所对应的IP地址。

  • 选项字段:不定长,最多40字节。

IP的解包

IP分离报头与有效载荷的方法与TCP是一模一样的,当IP从底层获取到一个报文后,虽然IP不知道报头的具体长度,但IP报文的前20个字节是IP的基本报头,并且这20字节当中涵盖4位首部长度。

因此IP是这样分离报头与有效载荷的:

  • 当IP从底层获取到一个报文后,首先读取报文的前20个字节,并从中提取出4位的首部长度,此时便获得了IP报头的大小sizesize size
  • 如果sizesize size的值大于20字节,则需要继续从报文当中读取size−20size − 20 size20 字节的数据,这部分数据就是IP报头当中的选项字段。
  • 读取完IP的基本报头和选项字段后,剩下的就是有效载荷了。

IP就是通过这种“定长报头+自描述字段”的方式进行报头和有效载荷的分离的。但需要注意的是,IP报头当中的4位首部长度描述的基本单位与TCP报头当中的4位首部长度一样,都是以4字节为单位进行描述的,这也恰好是报文的宽度。

IP的分用

在IP报头当中有一个字段叫做8位协议,该字段表示的就是上层协议的类型,IP就是根据该字段判定应该将分离出来的有效载荷交付给上层的哪一个协议的。该字段是发送方的IP层从上层传输层获取到数据后填充的,比如是上层TCP交给IP层的数据,那么该数据在封装IP报头时的8位协议填充的就是TCP对应的编号。

8位生存时间

报文在网络传输过程中,可能因为某些原因导致报文无法到达目标主机,比如报文在路由时出现了环路路由的情况,或者目标主机已经异常离线了,此时这个报文就成了一个废弃的游离报文。

为了避免网络当中出现大量的游离报文,于是在IP的报头当中就出现了一个字段,叫做8位生存时间(Time To Live,TTL)。8位生存时间代表的是报文到达目的地的最大报文跳数,每当报文经过一次路由,这里的生存时间就会减一,当生存时间减为0时该报文就会被自动丢弃,此时这个报文就会在网络中消散。

TTL 的值一般是 64,Linux 将 MSL 设置为 60 秒,意味着 Linux 认为数据报文经过 64 个路由器的时间不会超过 60 秒,如果超过了,就认为报文已经消失在网络中了。

三、分片与组装

IP能够将数据跨网络从一台主机送到另一台主机,而数据在进行跨网络传送时,需要经过一个个的路由器进行路由转发,最终才能到达目标主机。

因此IP进行数据跨网络传送的前提是,需要先将数据从一个节点传送到和自己相连的下一个节点,这个问题实际就是由IP之下的数据链路层解决的,其中数据链路层最典型的代表协议就是MAC帧。

而两个节点直接相连也就意味着这两个节点是在同一个局域网当中的,因此要讨论两个相邻节点的数据传送时,实际讨论的就是局域网通信的问题。

1、最大传输单元 MTU

MAC帧作为数据链路层的协议,它会将IP传下来的数据封装成数据帧,然后发送到网络当中。但MAC帧携带的有效载荷的最大长度是有限制的,也就是说IP交给MAC帧的报文不能超过某个值,这个值就叫做最大传输单元(Maximum Transmission Unit,MTU)。

每种数据链路的最大传输单元 MTU 都是不相同的,例如 FDDI 数据链路 MTU 4352、我们最常见数据链路是以太网 其MTU 是 1500 字节。

每种数据链路的 MTU 之所以不同,是因为每个不同类型的数据链路的使用目的不同。使用目的不同,可承载的 MTU 也就不同。

在Linux下使用ifconfig命令可以查看对应的MTU大小:

那么当 IP 数据包(包括IP的报头和IP的有效载荷)大小大于 MTU 时, IP 数据包就会被分片。

2、分片和组装的宏观过程

假设我们现在有一个比较大的数据要发送,这个数据需要在IP层进行分片。

经过分片之后的 IP 数据报在被重组的时候,只能由目标主机进行,路由器是不会进行重组的

一些注意要点:

  • 数据的分片是少数情况,实际在网络通信过程中不分片才是常态,因为数据分片会存在一些潜在的问题,比如分片可能会增加丢包的概率。

  • 数据的分片和组装发生在IP层,不仅源端主机可能会对数据进行分片,数据在路由过程中的路由器也可能对数据进行分片。因为不同的数据链路类型的 MTU 是不一样的,如果传输路径上的某个数据链路类型 的MTU比源端数据链路类型的MTU小,那么路由器就可能对IP数据报再次进行分片。

  • 分片数据的组装只会发生在目的端的IP层

  • 在分片的数据中,每一个分片在IP层都会被添加上对应的IP报头,而传输层添加的报头只会出现在第一个分片中,因此网络中传输的数据包可能没有传输层的报头。


问:在IP层进行数据分片,是否会影响上层传输层或者下层的数据链路层

答案是:数据的分片和组装都是在IP层完成的,上层的传输层和下层的链路层并不关心

传输层只负责为数据传送提供可靠性保证,比如当数据传送失败后,传输层的TCP协议可以组织进行数据重传。

  • 当TCP将待发送的数据交给IP后,TCP并不关心该数据是否会在IP层进行分片,即TCP并不关心数据具体的发送过程。
  • 当TCP从IP获取到数据后,TCP也不关心该数据是否在IP层经过了组装。

而链路层的MAC帧只负责,将数据从一个节点传送到和自己相连的下一个节点。

  • 当IP将待发送的数据交给MAC帧后,MAC帧并不知道该数据是IP经过分片后的某个分片数据,还是一个没有经过分片的数据,MAC帧只知道它一次最多只能发送MTU大小的数据,如果IP交给MAC帧大于MTU字节的数据,那MAC帧就无法进行发送。
  • 当MAC帧从网络中获取到数据后,MAC帧也不关心这个数据是否需要进行组装,MAC帧只需要将该数据的MAC帧报头去掉后直接上交给上层IP就行了,而至于该数据的组装问题则是IP需要解决的。

因此,数据的分片和组装完全是由IP协议自己完成的,传输层和链路层不必关心也不需要关心。


3、分片的详细过程

假设IP层要发送4500字节的数据,由于该数据超过了MAC帧规定的MTU,因此IP需要先将该数据进行分片,然后再将一个个的分片交给MAC帧进行发送。

IP报头如果不携带选项字段,那么其大小就是20字节,假设IP层添加的IP报头的长度就是20字节,并按下列方式将数据分片后形成了四个分片报文:

分片报文总字节数IP报头字节数数据字节数
11500201480
21500201480
31500201480
4802060

需要注意的是:分片后的每一个分片数据都需要封装上对应的IP报头,因此4500字节的数据至少需要分为四个分片报文进行发送。

分片报文到达对方的IP层后需要被重新组装起来,因此IP层在对数据进行分片时需要记录分片的信息,而IP报头当中的16位标识、3位标志和13位片偏移实际就是与数据分片相关的字段。

假设原始报文的标识是123,则四个分片报文的16位标识也应该都是123,四个报文对应的16位标识、3位标志和13位片偏移分别如下:

分片报文总字节数IP报头字节数数据字节数16位标识3位标志13位片偏移
115002014801230010
21500201480123001185
31500201480123001370
4802060123000555

需要注意的是,13位片偏移当中记录的字节数是当前分片在原数据开始处的偏移字节数的值 ÷ 8÷ 8÷8得到的,比如分片报文2在原始数据开始处的偏移字节数是1480,其对应的13位片偏移的值就是 1480 ÷ 8 = 1851480 ÷ 8 = 1851480÷8=185

4、组装的详细过程

Ⅰ. 如何区分不同客户端的数据或者同一个客户端的不同数据

首先,MAC帧交给IP层的数据可能是来自多个客户端的,而且这些数据可能是经过分片后发送的,也可能是没有经过分片直接发送的,因此IP必须先要通过某种方式来区分收到的各个数据。

  • 区分不同的客户端:IP报头当中有32位源IP地址,源IP地址记录了发送端所对应的IP地址,因此通过IP报头当中的32位源IP地址就可以区分来自不同客户端的数据。

  • 区分数据是否经过了分片:IP报头当中有16位标识,未分片的数据各自的16位标识都是不同的,而由同一个数据分片得到的各个分片报文所对应的16位标识都是相同的,因此通过IP报头当中16位标识就可以判断哪些报文是没有经过分片的独立报文,哪些报文是经过分片后的分片报文。

因此可以通过IP报头当中的32位源IP地址区分不同客户端的分片,通过16位标识区分同一个客户端的不同分片,将经过分片的数据各自聚合在一起,聚合在一起后就可以开始进行组装了。

Ⅱ. IP协议怎么知道数据是经过分片了呢” />if((更多分片 == 0) || (13位片偏移 == 0)) {// 未经过分片的IP报文...}else{// 经过分片的IP报文,需要进行组装...}

Ⅲ. IP协议怎么把分片组装在一起呢?

经过前面问题的讨论,我们已经能够将经过分片的数据各自聚合在一起了,聚合在一起后就可以开始进行组装了。

根据分片报文的个特点:

  1. 先找到分片报文中13位片偏移为0的分片报文(分片首部),然后提取出其IP报头当中的「16位总长度」字段,然后通过当前报文的数据字节数=16位总长度−4位首部长度。当前报文的数据字节数 =16位总长度 – 4位首部长度。 当前报文的数据字节数=16位总长度4位首部长度。

  2. 得到当前报文的数据字节数,然后进行计算下一个分片报文的所对应的13位片偏移
    下一个分片报文的13位片偏移=当前报文的13位片偏移+当前报文的数据字节数÷8下一个分片报文的13位片偏移 = 当前报文的13位片偏移 + 当前报文的数据字节数 ÷ 8 下一个分片报文的13位片偏移=当前报文的13位片偏移+当前报文的数据字节数÷8

  3. 然后寻找对应的13位片偏移匹配的分片进行拼接,然后在循环第二步第三步,直到拼接到一个更多分片标志位为0的分片报文,此时表明分片报文组装完毕。

Ⅳ. IP协议怎么保证你把分片收全了?

这个问题很简单,当IP协议进行把分片组装时,会进行13位片偏移的计算与查找,如果分片缺失就会导致组装时查找不到对应的分片,于是IP协议就知道分片丢失了。

Ⅴ. IP协议怎么保证组合在一起的报文一定是对的?

IP协议单独工作是没有办法保证组合在一起的数据不会出现问题,只有当TCP/UDP与IP协同工作时才能保证组合在一起的数据是正确的!

首先IP协议报头中含有一个,「16位首部校验和」所以通过这个字段我们能够保证IP报头不会出现问题,即IP的组装过程没有问题。

然后IP向上进行交付给TCP/UDP时,TCP/UDP的包头中有一个「16位校验和」于是TCP/UDP就可以根据这个字段进行对TCP/UDP整体报文(报头+有效载荷)判断报文有没有受损,于是就保证了报文一定是正确的。

5、分片的其他相关问题

Ⅰ、为什么不建议进行分片?

虽然传输层并不关心IP层的分片问题,但分片对传输层也是有影响的。

  • 如果一个数据在网络传输过程中没有经过分片,那么只要接收端收到了这一个报文,我们就可以认为该数据被对方可靠的收到了。而如果一个数据在网络传输过程中进行了分片,那么只有当接收端收到了全部的分片报文并将其成功组装起来,这时我们才认为该数据被对方可靠的收到了。

  • 但如果众多的分片报文当中有一个报文出现了丢包,就会导致接收端就无法将报文成功组装起来,这时接收端会将收到的分片报文全部丢弃,此时传输层TCP会因为收不到对方应答而进行超时重传。

假设在网络传输时丢包的概率是万分之一,如果将数据拆分为一百份进行发送,那么此时丢包的概率就上升到了百分之一(概率的加法原理)。因为只要有一个分片报文丢包了也就等同于这个报文整体丢失了,因此分片会增加传输层重传数据的概率。

需要注意的是,只要分片报文当中的某一个出现了丢包,此时传输层都需要将数据整体进行重传,因为传输层并不知道底层IP对数据进行了分片,当传输层发送出去的数据得不到应答时传输层就只能将数据整体进行重传,因此数据在发送时不建议进行分片。

Ⅰ、如何尽可能避免分片?

实际数据分片的根本原因在于传输层一次向下交付的数据太多了,导致IP无法直接将数据向下交给MAC帧,如果传输层控制好一次交给IP的数据量不要太大,那么数据在IP层自然也就不需要进行分片。

  • 因此TCP作为传输控制协议,它需要控制一次向下交付数据一般不能超过某一阈值,这个阈值就叫做MSS(Maximum Segment Size,最大报文段长度),TCP进行重传时也是以 MSS 为单位

  • 通信双方在建立TCP连接时,除了需要协商自身窗口大小等概念之外,还会协商后续通信时每一个报文段所能承载的最大报文段长度MSS。

  • MAC帧的有效载荷最大为MTU,TCP的有效载荷最大为MSS,由于TCP和IP常规情况下报头的长度都是20字节,因此一般情况下 M S S = M T U − 20 − 20MSS = MTU – 20 – 20MSS=MTU2020,而以太网MTU的值是1500字节,因此MSS的值一般就是1460字节。

所以一般建议TCP将发送的数据控制在1460字节以内,此时就能够降低数据分片的可能性。之所以说是降低数据分片的可能性,是因为每个网络的链路层对应的MTU可能是不同的,如果数据在传输过程中进入到了一个MTU较小的网络,那么该数据仍然可能需要在路由器中进行分片。

四、网段划分

1、IP地址的构成

IP地址由网络号和主机号两部分构成:

  • 网络号: 保证相互连接的两个网段具有不同的标识。
  • 主机号: 同一网段内, 主机之间具有相同的网络号, 但是必须有不同的主机号。

在网络中有一种表示方法:可以在IP地址的后面加一个 /,并在 / 后面加上一个数字,这就表示从第一个比特位开始到第几位为止属于网络号。

例如,下图中路由器连接了两个网段。对于网络标识来讲,同一网段内主机的网络标识是相同的,不同网段内主机的网络标识是不同的。而对于主机标识来讲,同一网段内主机的主机标识是不同的,不同网段内主机的主机标识是可以相同的。

  • 不同的子网其实就是把网络号相同的主机放到一起。
  • 如果在子网中新增一台主机,则这台主机的网络号和这个子网的网络号一致,但是主机号必须不能和子网中的其他主机重复。
  • 由于路由器要进行跨网路传输所以路由器要同时属于多个子网,而且其主机号一般都是1,因为一个子网内一般最先进行连接的就是路由器。

2、DHCP协议

通过合理设置主机号和网络号, 就可以保证在相互连接的网络中, 每台主机的IP地址都不相同,但是手动管理子网内的IP, 是一个相当麻烦的事情。

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

3、IP 地址的分类

互联网诞生之初,IP 地址显得很充裕,于是计算机科学家们设计了分类地址。

IP 地址分类成了 5 种类型,分别是 A 类、B 类、C 类、D 类、E 类。

上图中黄色部分为分类号,用以区分 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千多个主机,但是我没有使用完,但是我的网络号还不能让出去,于是我占了一个网络号就会占有大量的IP地址, A类地址的子网内的主机数更多。

然而实际网络架设中, 不会存在一个子网内有这么多的情况. 因此大量的IP地址都被浪费掉了。

Ⅰ、无分类地址 CIDR

针对这种情况提出了新的划分方案, 称为CIDR(Classless Interdomain Routing),CIDR是兼容上面的划分方案的:

  • 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号;
  • 子网掩码也是一个32位的正整数, 通常左半边全是1右半边全是0;
  • 将IP地址和子网掩码进行 按位与操作, 得到的结果就是网络号;
  • 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关。

例如下面网络号的计算:

划分子网

通过子网掩码划分出网络号和主机号,子网掩码最重要的作用就是:「划分子网」

子网划分实际上是将主机地址分为两个部分:子网网络地址和子网主机地址。形式如下:

  • 未做子网划分的 ip 地址:网络地址+主机地址
  • 做子网划分后的 ip 地址:网络地址+(子网网络地址+子网主机地址)

假设对 C 类地址进行子网划分,IP地址 192.168.1.0,使用子网掩码 255.255.255.192 对其进行子网划分。

C 类地址中前 24 位是网络号,最后 8 位是主机号,根据子网掩码可知从 8 位主机号中借用 2 位作为子网号

通过子网掩码此时一个网络就被更细粒度的划分成了一个个更小的子网,通过不断的子网划分,子网中IP地址对应的主机号就越来越短,因此子网当中可用IP地址的个数也就越来越少,这也就避免了IP地址被大量浪费的情况。

在Linux和Windows下,我们分别可以使用ifconfig/ipconfig来进行查看子网掩码:

Linux下:

Windows下:

Ⅱ、特殊的IP地址

并不是所有的IP地址都能够作为主机的IP地址,有些IP地址本身就是具有特殊用途的。

  • 将IP地址中的主机地址全部设为0,就成为了网络号,代表这个局域网。
  • 将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包。
  • 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1。

因此在某个局域网中最多能存在的主机个数是 : 2主机号位数− 22^{主机号位数 } − 22主机号位数2,这个2就是两个特殊的IP,分别是主机号全为 1 和 全为 0 地址。

本机环回基本原理

本机环回的目的就是将数据自顶向下贯穿协议栈,进行一次数据封装的过程的过程,然后再自底向上贯穿协议栈,进行一次数据的解包和分用,用于测试本地的网络功能是否正常。

需要注意的是:计算机以回环地址发送的消息,并不会由数据链路层送走,而是被本机网络层捕获

loopback设备:

基本原理

  • 当数据到达IP层需要继续向下交付时,如果是环回程序,那么IP输出函数会将该数据放入到IP输入队列当中,然后再由IP输入函数读取上去。
  • 而IP输入函数将数据读取上去的本应该是链路层交付上来的数据,因此该数据后续就会被当作从网络中读取上来的数据看待,各层协议会对该数据依次进行解包和分用。
  • 如果不是环回程序的话,那么接下来就会判断该数据对应的目的IP地址是否为广播或多播地址,或者目的IP地址是否与本主机的IP地址相同,如果是则也会将该数据放入到IP输入队列当中,等待IP输入函数将其读走。
  • 只有判断程序不是环回程序,并且也不是广播或多播,或发给本主机的数据后,才会用ARP获取该数据目的主机的以太网地址并进行后续数据发送的操作。

4、公有IP与私有IP

Ⅰ、IP地址的数量限制

我们知道,IP地址(IPv4)是一个4字节32位的正整数,因此一共有 232 2^{32}232 个IP地址,也就是将近43亿个IP地址。但TCP/IP协议规定,每个入网的主机都需要有一个IP地址。

现在全世界人口已经有70多亿了,就算有一半的人没有智能手机,算下来也有30多亿台智能手机需要IP地址,随着科技的发展,我们使用的电脑、智能手表、智能冰箱、智能洗衣机等设备如果要入网也是需要IP地址的。

另外,IP地址并不是按照主机台数来配置的,因此一个主机可能需要多个IP地址,更别谈还有很多组网的路由设备也需要IP地址,以及一些特殊的IP地址不能使用的问题。

所以43亿个IP地址其实早就不够用了,因此才提出了CIDR的方案对已经划分好的五类网络继续进行子网划分,其目的就是为了减少IP地址的浪费,提供IP地址的使用率,CIDR虽然在一定程度上缓解了IP地址不够用的问题,但IP地址的绝对上限并没有增加。

现在解决IP地址不足有以下几种方式:

  • 动态分配IP地址:只给接入网络的设备分配IP地址,因此同一个MAC地址的设备,每次接入互联网中,得到的IP地址不一定是相同的,避免了IP地址强绑定于某一台设备。
  • NAT技术:能够让不同局域网当中同时存在多个相同的IP地址,NAT技术不仅能解决IP地址不足的问题,而且还能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。
  • IPv6:IPv6用16字节128位来表示一个IP地址,能够大大缓解IP地址不足的问题。但IPv6并不是IPv4的简单升级版,它们是互不相干的两个协议,彼此并不兼容,导致了IPv6的普及进展缓慢。

于是全球目前主流的解决IP地址不足采用的方案是NAT技术

Ⅱ、私有IP

因为IP地址的有限性和网络管理的需要,私有IP地址和公网IP地址的出现了。

如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,理论上使用任意的IP地址都可以,但是RFC 1918规定了用于组建局域网的私有IP地址。

私网IP地址的范围

  • 10.*,前8位是网络号,共16,777,216个地址。
  • 172.16.到172.31.,前12位是网络号,共1,048,576个地址。
  • 192.168.*,前16位是网络号,共65,536个地址。

私有IP的一些特点:

  • 私有IP地址不能出现在公网上。
  • 私有IP在不同的局域网内是可以重复的,在同一局域网内是不能重复的。

我们在windows下可以输入ipconfig来查看我们的IP地址可以看到是私有IP地址,而且你的也可能和我的IP的IP地址一样哦~,因为我们在不同的局域网中使用的都是私有IP。

因为私有IP在不同的局域网内可以重复,所以IP地址的数量就大大的增加了,但是私有IP是不能够直接出现在公网上,所以当我们使用私有IP进行上公网时还需要进行NAT转换来帮助我们访问公网。

平时我们办公室、家里、学校用的 IP 地址,一般都是私有 IP 地址。

Ⅲ、公有IP

公有IP就是我们在公网上面能够直接访问的IP,互联网公司提供的服务都是在公网上的,因为只有这样全世界的人才能访问。

问:公网IP很珍贵,那么公有 IP 地址由谁管理呢?

私有 IP 地址通常是内部的 IT 人员管理,公有 IP 地址是由 「ICANN」 组织管理,中文叫「互联网名称与数字地址分配机构」。

「IANA」 是 「ICANN」 的其中一个机构,它负责分配互联网 IP 地址,是按地理上面的州的方式层层分配。

  • ARIN 北美地区
  • LACNIC 拉丁美洲和一些加勒比群岛
  • RIPE NCC 欧洲、中东和中亚
  • AfriNIC 非洲地区
  • APNIC 亚太地区

其中,在中国是由 CNNIC 的机构进行管理,它是中国国内唯一指定的全局 IP 地址管理的组织。

五、网络结构

1、公网网络结构

由于网络是要进行全球通信的,所以网络就要能够将所有的国家都连接起来,但是为了能够更好的在全球网络中寻找某一台特定的主机就需要对全球网络进行组织管理,于是全球网络就按照了一种图方式进行组织起来了。

首先将所有的国家的跨国路由设备连接起来,形成全球公网,然后每个国家将自己的行政区的路由设备连接起来,形成了国家级别的公网,对行政区才用同样的结构,行政区在进行向下进行管理…,于是就出现了类似与下图的结构:

假设我们拥有公网IP的情况下:我们想要访问github网站,其过程大致如下:

  1. 由于github在美国,我们就需要将自己的请求发送给当地的路由设备,当地的路由设备,进行路由查找,发现找不到,于是将请求发送给当地的市的路由器。
  2. 当地市的路由设备,进行路由查找,发现找不到,于是将请求发送给当地的省的路由器。
  3. 跨国路由找不到,但是跨国路由能够分辨出这个报文应该是要转发那个国家的,最后由跨国路由器进行转发给美国的跨国路由,再由美国的跨国路由进行同样的路由查找最后找到github,进行请求,最后按照同样的方式进行返回。

2、私网网络结构

全球按照上面的划分方式,IP地址是远远不够的,所以当划分到了一定情况时,通信运营商为了保证每个人都能够上网就需要组建大型的局域网(私网),在大型的局域网中组建小型的局域网来保证每个人都能够上网,由于私网中IP是可以重复的所以这也就几乎解决了IP地址的不足问题。

路由器是连接两个或多个网络的硬件设备,其不仅能够进行数据转发还具有构建子网的能力(所以我们连接路由器就是在连接路由器构建的子网),在路由器上有两种网络接口,分别是LAN口和WAN口:

  • LAN口(Local Area Network):表示连接本地网络的端口,主要与家庭网络中的交换机、集线器或PC相连,路由器LAN口连接的主机, 都从属于当前这个路由器的子网中。
  • WAN口(Wide Area Network):表示连接广域网的端口,一般指互联网。

我们将LAN口的IP地址叫做LAN口IP,也叫做子网IP,将WAN口的IP地址叫做WAN口IP,也叫做外网IP。


例如借助下图说明内网IP是怎么访问公网IP的,我们是一个IP为192.168.1.201/24的内网IP,我们要访问公网IP为122.77.241.3/24的服务器。

  • 首先我们要进行访问公网中的服务器,我们需要先将数据交给家用路由器让家用路由器帮我们进行路由选择,家用路由器查路由表没有找到,于是由家用路由器向上交付给运营商路由器,但是交付之前要对我们的IP报文进行LAN口IP转化为WAN口IP,于是我们的IP报文的源地址就被修改为了10.1.1.2/24,但是目标IP地址不变。

  • 运营商路由器进行查询路由表,发现找到了公网IP为122.77.241.3/24的服务器,但是由于我们现在的IP报文的IP地址还是一个内网IP,不能够直接出现在公网上,但是运营商路由器的WAN口IP是一个公网IP,于是继续进行LAN口IP转换为WAN口IP,于是我们的IP报文的源地址就被修改为了122.77.241.4/24,但是目标IP地址不变。

  • 替换后的报文经过公网转发给了目标服务器,目标服务器处理后进行响应,于是目标服务器根据IP报文的源地址是122.77.241.4/24构建响应,将数据发送给了运营商路由器。

  • 接下来运营商路由器就要能够将响应的报文再发送给我们的家用的路由器,家用的路由器再将响应发送给我们指定的内网IP,当然这个报文返回的过程中的中间的细节涉及NAT技术,我们在后续的文章中会详细介绍NAT技术。

可以看出我们只需要在运营商的路由器出口处,配置一个公网IP,就能够让一个大的局域网内的所有内网IP的主机都能够进行访问公网,这极大的解决了IP地址不足的问题。

思考:两个局域网当中的主机不能不跨公网进行通信?

  • 两个局域网当中的主机理论上是不能不跨公网进行通信的,因为一个主机要将数据发送给另一台主机的前提是得先知道另一台主机的IP地址。
  • 即便现在这个主机知道了另一台主机的IP地址,但有可能这两台主机的IP地址是一样的,因为它们的IP地址都是私网IP地址。
  • 当这一台主机发送数据时将目的IP地址填成和自己相同的IP地址,操作系统就会认为这个数据就是要发给自己的,而不会向外进行发送了。

所以数据要从一个局域网发送到另一个局域网,如果不经过公网是基本上不可能的。我们在和别人聊天的时候,是先将数据经过公网发送到了服务器,然后再由服务器将数据经过公网转发到了另一个局域网。

但实际确实存在一些技术能够使数据包在发送过程中不进行公网IP的替换,而将数据正确送到目标主机,这种技术叫做内网穿透,也叫做NAT穿透。

六、路由

1、路由过程的宏观介绍

路由其实就是:在复杂的网络结构中, 找出一条通往终点的路线。

数据在路由的过程中,实际就是一跳一跳(Hop by Hop)“问路”的过程。所谓“一跳”就是数据链路层中的一个区间,具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间。

IP数据包的传输过程中会遇到很多路由器,这些路由器会帮助数据包进行路由转发,每当数据包遇到一个路由器后,对应路由器都会查看该数据的目的IP地址,并告知该数据下一跳应该往哪跳。

路由器的查找结果可能有以下三种:

  • 路由器经过路由表查询后,得知该数据下一跳应该跳到哪一个子网。
  • 路由器经过路由表查询后,没有发现匹配的子网,此时路由器会将该数据转发给默认路由。
  • 路由器经过路由表查询后,得知该数据的目标网络就是当前所在的网络,此时路由器就会将该数据转给当前网络中对应的主机。

网关

大家都知道,从一个房间走到另一个房间,必然要经过一扇门。同样,主机从一个局域网向另一个局域网内的主机发送信息,也必须经过一道“关口”,这道关口就是网关。顾名思义,网关(Gateway)就是一个网络连接到另一个网络的“关口”。

就好像一个房间可以有多扇门一样,一台主机可以有多个网关,默认网关的意思是一台主机如果找不到可用的网关,就把数据包发给默认指定的网关,由这个网关来处理数据包,一般情况下(家用网络环境或较小的网络环境),默认网关就是我们的路由器设备。

Windows电脑上,我们可以使用ipconfig查看我们的默认网关:

Linux 中我们可以使用ip route查看我们的默认网关:


每个路由器内部会维护一个路由表,我们可以通过route命令查看云服务器上对应的路由表,(主机内部是有路由器的)。

  • Destination:代表的是目的网络地址,也就是当前路由器与正在与那些网络相连接着呢。
  • Gateway :通往目标网络的下一跳IP地址,通常情况下,这个下一跳地址是路由器或网关的IP地址。
  • Genmask:代表的是子网掩码。
  • Flags :中,U标志表示此条目有效(可以禁用某些条目)G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发。
  • Iface:代表的是发送接口,相当于网卡的网口。

路由过程:

当IP数据包到达路由器时,路由器就会用该数据的目的IP地址,依次与路由表中的子网掩码 Genmask进行“按位与”操作,然后将结果与子网掩码对应的目的网络地址Destination进行比对,如果匹配则说明该数据包下一跳就应该跳去这个子网,此时就会将该数据包通过对应的发送接口Iface发出。

如果将该数据包的目的IP地址与子网掩码进行“按位与”后,没有找到匹配的目的网络地址,此时路由器就会将这个数据包发送到默认路由,也就是路由表中目标网络地址中的default。可以看到默认路由对应的FlagsUG,实际就是将该数据转给了另一台路由器,让该数据在另一台路由器继续进行路由。

数据包不断经过路由器路由后,最终就能到达目标主机所在的目标网络,然后后续的报文交付就要交给数据链路层来执行了。

2、路由表生成算法(了解)

路由可分为静态路由和动态路由:

  • 静态路由:是指由网络管理员手工配置路由信息。
  • 动态路由:是指路由器能够通过算法自动建立自己的路由表,并且能够根据实际情况进行调整。

路由表相关生成算法:距离向量算法、LS算法、Dijkstra算法等。

3、一个简单的通信流程

当一台计算机需要和另一台计算机通讯时,计算机需要根据 本机IP 和 本机的子网掩码 得出本机所在的网段, 然后再根据本机子网掩码和目标IP地址 计算出目标IP所在的网段,如果两个网段相同,那么两台计算机是局域网,然后则开始借助数据链路层进行通信;如果不同,也就意味着目标IP是一个其他远程地址,这时候本机会把数据发送给默认网关,然后默认网关处理接下来的通信…

可以看出到最后经过IP的路由我们最后能到达一个局域网内,在一个局域网内的通信细节就要涉及数据链路层的一些协议了,那么我们下一期在进行讲解数据链路层的协议。