
Ⅰ. 基本概念
1、网络层解决的问题
TCP
作为传输层控制协议,其保证的是数据传输的可靠性和传输效率,但 TCP
提供的仅仅是数据传输的策略,而 真正负责数据在网络中传输的则传输层之下的网络层和链路层。
也就是说,双方在进行网络通信时,发送的数据并不是直接从一方的传输层直接发送到了另一方的传输层,而是需要传输层将数据继续向下进行交付,在网络层和链路层经过数据封装后再通过网络发送到对方主机,对方主机收到数据后也同样需要在链路层和网络层进行数据解包,此时对方的传输层才拿到了发送过来的数据,然后再继续将该数据向上进行交付。
网络通信的过程,就像两个人在送互相送数据,这两个人分别在两栋楼的四楼,如果一个人要将数据交给对方,那么这个人就必须先从四楼走到一楼,然后再在路上经过路径选择到达对方楼下,最后再上到四楼将数据交给对方。
其中,送数据的这个人从四楼下来的过程就是数据封装的过程,这个人在路上经过路径选择到达对方楼下的过程就是数据路由的过程,而这个人再上到四楼将数据交给对方的过程就是数据解包的过程。
而 网络层要解决的问题就是如何将数据从一台主机送到另一台主机,也就是数据的路由。
2、保证数据可靠的从一台主机送到另一台主机的前提
当双方在进行基于 TCP
的网络通信时,要保证将数据可靠的从一台主机送到另一台主机,前提是发送方要有将数据发送到对方主机的能力,要是发送方连将数据发送给对方的能力都没有,那就更不用谈可靠的将数据送给对方主机了。
需要注意的是,发送方有将数据送到对方主机的能力,并不意味着发送方每次发送的数据都能够成功的发送到对方,但如果发送方连将数据发送给对方的能力都没有,那发送方基本就不可能将数据发送给对方。
一旦发送方有了将数据发送给对方的能力,就算发送方某次发送的数据没有成功到达对方,此时上层
TCP
由于没有收到对应数据的应答,TCP
就会要求进行数据重发,直到数据成功发送到对方主机为止。
也就是说,在网络层有能力将数据送到对方主机的情况下,虽然网络层不能保证每次都能将数据成功送到对方主机,但在 TCP
提供的可靠性策略的保证下,最终网络层就一定能够将数据可靠的发送到对方主机。
说明一下:
- 一方传输层从上方进程拿到数据后,该数据贯穿网络协议栈进行封装和解包,最终到达对方传输层,此时对方传输层也会将数据向上交给对应的进程,因此传输层解决的是进程到进程的问题。
3、路径选择
数据进行的网络传输一般都是跨网络的,而路由器就是连接多个网络的硬件设备,因此数据在进行跨网络传输时一定需要经过多个路由器。
数据路由就像我们旅游一样,当确定了要到达的目标主机后,就需要寻找最短的路径到达该目的地。
目的地的确定是非常重要的,因为目的地直接决定了数据路由时的路径选择,这也是跨网络找到目标主机的根本。
只有数据经过了较为正确的路径选择,最终才可能慢慢趋近于目标网络或目标主机。
确定数据路由的目的地后,数据就可以在网络中进行路由了,但数据在路由时无法自行进行路径选择,因为这个数据本身是 “不认识路” 的,因此数据在路由的过程中需要不断 “找路人问路”,而这里所谓的 “路人” 就是网络当中的一台台 路由器。
网络当中的路由器是 “认识路的”,它们将自己的 “认路经验” 都记录到路由表当中,因此路由器可以通过查路由表找到去特定点的最短路径。因此数据在路由时,会不断通过路由器来进行路径选择,以此来一步步靠近目标网络或目标主机!
也就是说,路径选择,其实就是 目标网络 + 目标主机!
4、主机和路由器的区别
主机:配有 IP
地址,但是不进行路由控制的设备。但实际现在几乎不存在不进行路由控制的设备了,就连你的笔记本也会进行路由控制。
路由器:既配有 IP
地址,又能进行路由控制。实际现在主流的路由器已经不仅仅具有路由的功能了,它甚至具备某些应用层的功能。
节点:主机和路由器的统称。
Ⅱ. IP协议格式
4
位版本号(version)- 指定
IP
协议的版本,对于IPv4
来说,就是4
,而IPv6
则是6
。
- 指定
4
位首部长度(header length)- 表示
IP
报头的长度,以4
字节为单位。所以因为其最大十进制数值是15
,算上单位的话,也就是4 * 15 = 60
字节,也就是说首部长度最大为60
字节!
- 表示
8
位服务类型(Type Of Service)- 3位优先权字段(已经弃用),4位TOS字段,和1位保留字段(必须置为0)。4位TOS分别表示:最小延时,最大吞吐量,最高可靠性,最小成本。这四者相互冲突,只能选择一个。比如对于ssh/telnet这样的应用程序,最小延时比较重要,而对于ftp这样的程序,最大吞吐量比较重要。一般情况下都不使用这个字段!
16
位总长度(total length)- 总长度指的是首部和有效载荷的总长度,单位是字节,这个字段用于将各个
IP
报文进行分离。其最大长度为2^16 - 1 = 65535
字节。 - 但是因为数据链路层中数据字段的最大长度,即 最大传送单元
MTU
(Maximum Transfer Unit
),一般规定其值为1500
字节,若传送的数据报长度超过该MTU
的话,就必须将过长的数据报进行分片处理。为此,IP
协议规定,在互联网中所有主机和路由器必须能够接收长度不超过576
字节的数据报(加上首部后)。
- 总长度指的是首部和有效载荷的总长度,单位是字节,这个字段用于将各个
16
位标识(identification)- 唯一的标识主机发送的报文,如果数据在
IP
层进行了分片,那么每一个分片对应的id
都是相同的。
- 唯一的标识主机发送的报文,如果数据在
3
位标志(flag)- 第一位保留,暂时没有规定该字段的意义。
- 第二位表示【禁止分片】,表示如果报文长度超过
MTU
,IP
模块就会丢弃该报文。 - 第三位表示【还有分片】,如果报文没有进行分片,则该字段设置为
0
,如果报文进行了分片,则除了最后一个分片报文设置为0
以外,其余分片报文均设置为1
。
13
位片偏移(framegament offset)表示当前分片相对于原始报文段开始处的偏移量,片偏移以
8
个字节为偏移单位。因此除了最后一个报文之外,其他报文的长度必须是8
的整数倍,否则报文在拼接的时候就不连续了。
8
位生存时间(Time To Live,TTL
)- 表示数据报在网络中的寿命,但本质是 数据报到达目的地的最大报文跳数,一般是
64
,每经过一个路由,就让跳数减一,直到减为零后,如果还没到达,那么就丢弃了,这个字段主要是用来 防止出现路由循环而造成的资源消耗。
- 表示数据报在网络中的寿命,但本质是 数据报到达目的地的最大报文跳数,一般是
8
位协议表示数据报携带的数据使用何种协议,这是为了方便目的主机的
IP
层知道应将数据部分上交给哪个协议进行处理!
16
位首部检验和- 使用
CRC
进行校验,来鉴别数据报的首部是否损坏,但不检验数据部分。下面是常见的协议及其对应字段值:
- 使用
32
位源IP
地址 &&32
位目的IP
地址- 表示发送端和接收端所对应的
IP
地址。
- 表示发送端和接收端所对应的
选项字段
- 不定长,最多
40
字节。
- 不定长,最多
和我们之前学过的传输层、应用层协议一样,IP
报头在内核当中本质就是一个位段类型,给数据封装 IP
报头时,实际上就是用该位段类型定义一个变量,然后填充 IP
报头当中的各个属性字段,最后将这个 IP
报头拷贝到数据的首部,至此便完成了 IP
报头的封装。
IP如何将报头与有效载荷进行分离?
IP
分离报头与有效载荷的方法与 TCP
是一模一样的,当 IP
从底层获取到一个报文后,从前 20
个字节中找到 4
位首部长度。因此 IP
是这样分离报头与有效载荷的:
当
IP
从底层获取到一个报文后,首先读取报文的前20
个字节,并从中提取出4
位的首部长度,此时便获得了IP
报头的大小size
。如果
size
的值大于20
字节,则需要继续从报文当中读取size−20
字节的数据,这部分数据就是IP
报头当中的选项字段。读取完
IP
的基本报头和选项字段后,剩下的就是有效载荷了。
IP
就是通过这种 定长报头+自描述字段 的方式进行报头和有效载荷的分离的。
IP如何决定将有效载荷交付给上层的哪一个协议?
基于 IP
协议的传输层协议不止一种,因此当 IP
从底层获取到一个报文并对其进行解包后,IP
需要知道应该将分离后得到的有效载荷交付给上层的哪一个协议。
在 IP
报头当中有一个字段叫做 8
位协议,该字段表示的就是上层协议的类型,IP
就是根据该字段判定应该将分离出来的有效载荷交付给上层的哪一个协议的。该字段是发送方的 IP
层从上层传输层获取到数据后填充的,比如是上层 TCP
交给 IP
层的数据,那么该数据在封装 IP
报头时的 8
位协议填充的就是 TCP
对应的编号。
理解socket编程
在进行 socket
编程的时候,当一端想要发送数据给另一端时,必须要指明对端的 IP
地址和端口号,也就是发送数据的目的 IP
地址和目的端口号。
其中这里的 IP
地址就是给网络层的 IP
用的,用于数据在网络传输过程中的路由转发,而这里的端口号就是给传输层的 TCP
或 UDP
用的,用于指明该数据应该交给上层的哪一个进程。
发送数据时我们不需要指明发送数据的源 IP
地址和源端口号,因为传输层和网络层都是在操作系统内核当中实现的,数据在进行封装时操作系统会自行填充上对应的源 IP
地址和源端口号。
Ⅲ. 分片与组装
1、数据链路层解决的问题
IP
能够将数据跨网络从一台主机送到另一台主机,而数据在进行跨网络传送时,需要经过一个个的路由器进行路由转发,最终才能到达目标主机。
比如要将数据从主机 B
跨网络传送到主机 C
,那么主机 B
需要先将数据交给路由器 F
,路由器 F
再将数据交给路由器 G
,…,最终由路由器 D
将数据交给主机 C
。
因此 IP
进行数据跨网络传送的前提是,需要先将数据从一个节点传送到和自己相连的下一个节点,这个问题实际就是由 IP
之下的数据链路层解决的,其中数据链路层最典型的代表协议就是 MAC
帧。
而两个节点直接相连也就意味着这两个节点是在同一个局域网当中的,因此要讨论两个相邻节点的数据传送时,实际讨论的就是局域网通信的问题。
2、最大传输单元 MTU
MAC
帧作为数据链路层的协议,它会将 IP
传下来的数据封装成数据帧,然后发送到网络当中。但 MAC
帧携带的有效载荷的最大长度是有限制的,也就是说 IP
交给 MAC
帧的报文不能超过某个值,这个值就叫做最大传输单元(Maximum Transmission Unit
,MTU
),这个值的大小 一般是 1500
字节。
在 Linux
下使用 ifconfig
命令可以查看对应的 MTU
。
由于 MAC
帧无法发送大于 1500
字节的数据,因此 IP
层向下交付的数据的长度不能超过 1500
字节,这里所说的数据包括 IP
的报头和 IP
的有效载荷。
3、分片与组装
如果 IP
层要传送的数据超过了 1500
字节,那么就需要先在 IP
层对该数据进行分片,然后再将分片后的数据交给下层 MAC
帧进行发送。
如果发送数据时在 IP
层进行了分片,那么当这些分片数据到达对端主机的 IP
层后就需要先进行组装,然后再将组装好的数据交付给上层传输层。
注意:
- 数据的分片不是经常需要做的,实际在网络通信过程中不分片才是常态,因为数据分片会存在一些潜在的问题,比如分片可能会增加丢包的概率。
- 数据的分片和组装发生在
IP
层,不仅源端主机可能会对数据进行分片,数据在路由过程中的路由器也可能对数据进行分片。因为不同网络的MTU
是不一样的,如果传输路径上的某个网络的MTU
比源端网络的MTU
小,那么路由器就可能对IP
数据报再次进行分片。 - 而分片数据的组装只会发生在目的端的
IP
层。 - 在分片的数据中,每一个分片在
IP
层都会被添加上对应的IP
报头,而传输层添加的报头只会出现在第一个分片中,因此网络中传输的数据包可能没有传输层的报头。
4、数据的分片和组装都是由IP层完成的
数据的分片和组装都是在 IP
层完成的,上层的传输层和下层的链路层并不关心。
传输层只负责为数据传送提供可靠性保证,比如当数据传送失败后,传输层的 TCP
协议可以组织进行数据重传。而链路层的 MAC
帧只负责将数据从一个节点传送到和自己相连的下一个节点。
- 当
IP
将待发送的数据交给MAC
帧后,MAC
帧并不知道该数据是IP
经过分片后的某个分片数据,还是一个没有经过分片的数据,MAC
帧只知道它一次最多只能发送MTU
大小的数据,如果IP
交给MAC
帧大于MTU
字节的数据,那MAC
帧就无法进行发送。- 当
MAC
帧从网络中获取到数据后,MAC
帧也不关心这个数据是否需要进行组装,MAC
帧只需要将该数据的MAC
帧报头去掉后直接上交给上层IP
就行了,而至于该数据的组装问题则是IP
需要解决的。
因此,数据的分片和组装完全是由 IP
协议自己完成的,传输层和链路层不必关心也不需要关心。
5、分片的过程
假设 IP
层要发送 4500
字节的数据,由于该数据超过了 MAC
帧规定的 MTU
,因此 IP
需要先将该数据进行分片,然后再将一个个的分片交给 MAC
帧进行发送。
IP
报头如果不携带选项字段,那么其大小就是 20
字节,假设 IP
层添加的 IP
报头的长度就是 20
字节,并按下列方式将数据分片后形成了四个分片报文:
需要注意的是,分片后的每一个分片数据都需要封装上对应的 IP
报头,因此 4500
字节的数据至少需要分为四个分片报文进行发送。
分片报文到达对方的 IP
层后需要被重新组装起来,因此 IP
层在对数据进行分片时需要记录分片的信息,而 IP
报头当中的 16
位标识、3
位标志和 13
位片偏移实际就是与数据分片相关的字段。
根据之前学过的协议字段,可以得到上述四个分片报文对应的 16
位标识都是一样的,假设四个分片报文的 16
位标识都是 123
,则这四个报文对应的 16
位标识、3
位标志中的“更多分片”和 13
位片偏移分别如下:
需要注意的是,13
位片偏移当中记录的字节数是当前分片在原数据开始处的偏移字节数的值除以 8
得到的,比如第二个分片报文在原始数据开始处的偏移字节数是 1480
,其对应的 13
位片偏移的值就是 1480 ÷ 8 = 185
。
6、组装的过程
MAC
帧交给 IP
层的数据可能来自世界各地,这些数据可能是经过分片后发送的,也可能是没有经过分片直接发送的,因此IP必须要通过某种方式来区分收到的各个数据。
IP
报头当中有32
位源IP
地址,源IP
地址记录了发送端所对应的IP
地址,因此通过IP
报头当中的32
位源IP
地址就可以区分来自不同主机的数据。IP
报头当中有16
位标识,未分片的数据各自的16
位标识都是不同的,而由同一个数据分片得到的各个分片报文所对应的16
位标识都是相同的,因此通过IP
报头当中16
位标识就可以判断哪些报文是没有经过分片的独立报文,哪些报文是经过分片后的分片报文。
因此 IP
协议可以 通过 IP
报头当中的 32
位源 IP
地址和 16
位标识,将经过分片的数据各自聚合在一起,聚合在一起后就可以开始进行组装了。
对于各个分片报文来说:
第一个分片报文中的
13
位片偏移的值一定为0
。最后一个分片报文中的“更多分片”标志位一定为
0
。对于每一个分片报文来说,当前报文的
13
位片偏移加上当前报文的数据字节数÷8
所得到的值,就是下一个分片报文的所对应的13
位片偏移。
根据分片报文的这三个特点就能够将分片报文合理的组装起来。
- 先找到分片报文中
13
位片偏移为0
的分片报文,然后提取出其IP
报头当中的16
位总长度字段,通过计算即可得出下一个分片报文所对应的13
位片偏移,按照此方式依次将各个分片报文拼接起来。- 直到拼接到一个“更多分片”标志位为
0
的分片报文,此时表明分片报文组装完毕。
7、分片报文丢包的问题
分片后的报文在网络传输过程中也可能会出现丢包问题,但接收端有能力判断是否收到了全部分片报文,比如假设某组分片报文对应的 16
位标识值为 x
:
如果分片报文中的第一个分片报文丢包了,那么接收端收到的分片报文中就找不到对应
16
位标识为x
,并且13
位片偏移为0
的分片报文。如果分片报文中的最后一个分片报文丢包了,那么接收端收到的分片报文中就找不到对应
16
为标识为x
,并且 “更多分片” 标志位为0
的分片报文。如果分片报文中的其它分片报文丢包了,那么接收端在进行分片报文的组装时就会找不到对应
13
位片偏移为特定值的分片报文。
需要注意的是,未分片报文的 “更多分片” 标志位为 0
,最后一个分片报文的“更多分片”标志位也为 0
,但当接收端只收到分片报文中的最后一个分片报文时,接收端不会将其识别成一个未分片的报文,因为未分片的报文所对应的 13
位片偏移的值也应该是 0
,而最后一个分片报文所对应的 13
位片偏移的值不为 0
。
因此只有当一个报文的 13
位片偏移为 0
,并且该报文的“更多分片”标志位也为 0
时,该报文才会被识别成一个没有被分片的独立报文,否则该报文就会被识别成一个分片报文。
8、为什么不建议进行分片?
虽然传输层并不关心 IP
层的分片问题,但分片对传输层也是有影响的。
- 如果一个数据在网络传输过程中没有经过分片,那么只要接收端收到了这一个报文,我们就可以认为该数据被对方可靠的收到了。
- 而如果一个数据在网络传输过程中进行了分片,那么只有当接收端收到了全部的分片报文并将其成功组装起来,这时我们才认为该数据被对方可靠的收到了。但如果众多的分片报文当中有一个报文出现了丢包,就会导致接收端就无法将报文成功组装起来,这时接收端会将收到的分片报文全部丢弃,此时传输层
TCP
会因为收不到对方应答而进行超时重传。- 假设在网络传输时丢包的概率是万分之一,如果将数据拆分为一百份进行发送,那么此时丢包的概率就上升到了百分之一。因为只要有一个分片报文丢包了也就等同于这个报文整体丢失了,因此分片会增加传输层重传数据的概率。
需要注意的是,只要分片报文当中的某一个出现了丢包,此时传输层都需要将数据整体进行重传,因为传输层并不知道底层 IP
对数据进行了分片,当传输层发送出去的数据得不到应答时传输层就只能将数据整体进行重传,因此数据在发送时不建议进行分片。
9、如何尽可能避免分片?
实际数据分片的根本原因在于传输层一次向下交付的数据太多了,导致 IP
无法直接将数据向下交给 MAC
帧,如果传输层控制好一次交给 IP
层的数据量不要太大,那么数据在 IP
层自然也就不需要进行分片。
因此
TCP
作为传输控制协议,它需要控制一次向下交付数据不能超过某一阈值,这个阈值就叫做MSS
(Maximum Segment Size
)最大报文段长度。通信双方在建立
TCP
连接时,除了需要协商自身窗口大小等概念之外,还会协商后续通信时每一个报文段所能承载的最大报文段长度MSS
。
MAC
帧的有效载荷最大为 MTU
,TCP
的有效载荷最大为 MSS
,由于 TCP
和 IP
常规情况下报头的长度都是 20
字节,因此一般情况下 MSS = MTU - 20 - 20
,而 MTU
的值一般是 1500
字节,因此 MSS
的值一般就是 1460
字节。
所以一般建议 TCP
将发送的数据控制在 1460
字节以内,此时就能够降低数据分片的可能性。之所以说是降低数据分片的可能性,是因为每个网络的链路层对应的 MTU
可能是不同的,如果数据在传输过程中进入到了一个 MTU
较小的网络,那么该数据仍然可能需要在路由器中进行分片。
Ⅳ. 网段的划分
1、IP地址的构成
IP
地址由网络号和主机号两部分构成:
- 网络号:保证相互连接的两个网段具有不同的标识。
- 主机号:同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号。
可以在 IP
地址的后面加一个 /
,并在 /
后面加上一个数字,这就表示从头数到第几位为止属于网络标识,这种划分 IP
地址的方式称为 无分类域间路由选择 CIDR
(Classless Inter-Domain Routing
)。
例如,下图中路由器连接了两个网段。对于网络标识来讲,同一网段内主机的网络标识是相同的,不同网段内主机的网络标识是不同的。而对于主机标识来讲,同一网段内主机的主机标识是不同的,不同网段内主机的主机标识是可以相同的。
不同的子网划分其实就是把网络号相同的主机放到一起。如果在子网中新增一台主机,则这台主机的网络号和这个子网的网络号一致,但是主机号必须不能和子网中的其他主机重复。
此外,一般在一个子网中管理 IP
地址的设备是路由器!
DHCP协议
实际手动管理 IP
地址是一个非常麻烦的事情,当子网中新增主机时需要给其分配一个 IP
地址,当子网当中有主机断开网络时又需要将其 IP
地址进行回收,便于分配给后续新增的主机使用。
- 因此对于
IP
地址的分配和回收一般不会手动进行,而是采用动态主机配置协议DHCP
(Dynamic Host Configuration Protocol
)技术。 DHCP
通常被应用在大型的局域网环境中,其主要作用就是集中地址管理、分配IP
地址,使网络环境中的主机动态获得IP
地址、网关地址、DNS服务器地址等信息,并能够提升地址的使用率。DHCP
是一个基于UDP
的应用层协议,一般的路由器都带有DHCP
功能,因此路由器也可以看作一个DHCP
服务器。
当我们连接 WiFi
时需要输入密码,本质就是因为路由器需要验证你的账号和密码,如果验证通过,那么路由器就会给你动态分配了一个 IP
地址,然后你就可以基于这个 IP
地址进行各种上网动作了。
先找目标网络,再找目标主机
当 IP
要将数据跨网络从一台主机发送到另一台主机时,其实不是直接将数据发送到了目标主机,而是先将数据发送到目标主机所在的网络,然后再将数据发送到目标主机。
因此数据在路由时的第一目的并不是找到目标主机,而是找到目标网络所在的网络,然后再在目标网络当中找到目标主机。
数据路由时之所以不一开始就以找目标主机为目的,因为这样效率太低了,没有很好的利用上网段划分的优势。
- 找主机的过程本质是排除的过程,如果一开始就以找目标主机为目的,那么在查找的过程中一次只能排除一个主机。
- 而如果一开始先以找目标网络为目的,那么在查找过程中就能一次排除大量和目标主机不在同一网段的主机,这样就可以大大提高检索的效率。
因此,为了提高数据路由的效率,我们对网络进行了网段划分。
2、网段划分
过去互联网曾提出一种划分网络号和主机号的方案,就是把所有 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
地址是属于哪一类时,只需要遍历 IP
地址的前五个比特位,第几个比特位最先出现 0
值,那么这个 IP
地址对应就属于哪类地址。
3、子网划分
但随着网络的飞速发展,上面这种划分方案的局限性很快就显现出来了。大多数组织都申请 B
类网络地址,导致 B
类地址很快就分配完了,而 A
类却浪费了大量地址。
比如一些学校、公司、实验室等组织想要申请自己的局域网,由于
A
类地址的网络号只占7
个比特位,可申请的网络号只有 2 7 2^7 27 个,于是大多数组织都选择申请B
类地址。 由于
B
类地址的主机号占16
个比特位,因此理论上一个B
类网络当中允许有65536
台主机。 但实际网络架设中,一般不会存在一个局域网当中有这么多主机的情况,也就意味着大量的
IP
地址实际都被浪费掉了。
为了避免这种情况,于是又提出了新的划分方案,称为 无分类域间路由选择 CIDR
(Classless Inter-Domain Routing
):
在原有的五类网络的基础上继续进行子网划分,这也就意味着需要借用主机号当中的若干位来充当网络号,此时为了区分 IP
地址中的网络号和主机号,于是引入了 子网掩码(subnet mask
)的概念。
每一个子网都有自己的子网掩码,子网掩码实际就是一个 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
地址当中的主机号的位数在不断减少。最终当数据路由到达目标主机所在的网络时,就可以在该网络当中找到对应的目标主机并将数据交给该主机,此时该数据的路由也就结束了。
4、特殊的IP地址
并不是所有的IP地址都能够作为主机的 IP
地址,有些 IP
地址本身就是具有特殊用途的。
- 将
IP
地址中的 主机地址全部设为0
,就成为了网络号,代表 这个局域网。- 将
IP
地址中的 主机地址全部设为1
,就成为了 广播地址,用于给同一个链路中相互连接的所有主机发送数据包。127.*
的IP
地址用于 本机环回(loop back
)测试,通常是127.0.0.1
。
也就是说,IP
地址中主机号为全 0
的代表的是当前局域网的网络号,IP
地址中主机号为全 1
的代表的是广播地址,这两个 IP
地址都是不能作为主机的 IP
地址的。
因此在 某个局域网中最多能存在的主机个数是 2 主机号位数 2^{主机号位数} 2主机号位数 - 2。
5、本机环回基本原理
本机环回会将数据贯穿网络协议栈,但最终并不会将数据发送到网络当中,相当于本机环回时不会将数据写到网卡上面。
本机环回的目的就是将数据自顶向下贯穿协议栈,进行一次数据封装的过程的过程,然后再自底向上贯穿协议栈,进行一次数据的解包和分用,用于测试本地的网络功能是否正常。
本机环回的基本原理:
- 当数据到达
IP
层需要继续向下交付时,如果是环回程序,那么IP
层输出函数会将该数据放入到IP
层输入队列当中,然后再由IP
层输入函数读取上去。- 而
IP
层输入函数将数据读取上去的本应该是链路层交付上来的数据,因此该数据后续就会被当作从网络中读取上来的数据看待,各层协议会对该数据依次进行解包和分用。- 如果不是环回程序的话,那么接下来就会判断该数据对应的目的
IP
地址是否为广播或多播地址,或者目的IP
地址是否与本主机的IP
地址相同,如果是则也会将该数据放入到IP
层输入队列当中,等待IP
层输入函数将其读走。- 只有判断程序不是环回程序,并且也不是广播或多播,或发给本主机的数据后,才会用
ARP
获取该数据目的主机的以太网地址并进行后续数据发送的操作。
Ⅵ. IP地址的数量限制
1、IP地址数量不足问题
我们知道,IPv4
是一个 4
字节 32
位的正整数,因此一共有 2 32 2^{32} 232 个IP地址,也就是将近 43
亿个 IP
地址。但 TCP/IP
协议规定,每个主机都需要有一个 IP
地址。
现在全世界人口已经有 70
多亿了,就算有一半的人没有智能手机,算下来也有 30
多亿台智能手机需要 IP
地址。随着科技的发展,我们使用的电脑、智能手表、智能冰箱、智能洗衣机等设备如果要入网也是需要 IP
地址的。
另外,IP
地址并不是按照主机台数来配置的,因此一个主机可能需要多个 IP
地址,更别谈还有很多组网的路由设备也需要 IP
地址,以及一些特殊的 IP
地址不能使用的问题。
所以 43
亿个IP地址其实早就不够用了,因此才提出了 CIDR
的方案对已经划分好的五类网络继续进行子网划分,其目的就是为了减少 IP
地址的浪费,根本原因就是 IP
地址本来就不够了,所以不能够再浪费了。
CIDR
虽然在一定程度上缓解了 IP
地址不够用的问题,因为 CIDR
提高了 IP
地址的利用率,减少了浪费,但 IP
地址的绝对上限并没有增加。
2、如何解决IP地址不足的问题
- 动态分配
IP
地址:只给接入网络的设备分配IP
地址,因此同一个MAC
地址的设备,每次接入互联网中,得到的IP
地址不一定是相同的,避免了IP
地址强绑定于某一台设备。 NAT
技术:能够让不同局域网当中同时存在两个相同的IP
地址,NAT
技术 不仅能解决IP
地址不足的问题,而且还能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。IPv6
:IPv6
用16
字节128
位来表示一个IP
地址,能够大大缓解IP
地址不足的问题。但IPv6
并不是IPv4
的简单升级版,它们是互不相干的两个协议,彼此并不兼容,因此目前IPv6
还没有普及。
Ⅶ. 私网IP地址和公网IP地址
1、私网IP地址的种类
如果一个组织内部组建局域网,IP
地址只用于局域网内的通信,而不直接连到互联网上,理论上使用任意的 IP
地址都可以,但是 RFC 1918
规定了用于组建局域网的私有 IP
地址。
10.0.0.0/8
:即从10.0.0.0
到10.255.255.255
,共 16,777,216 个地址。172.16.0.0/12
:即从172.16.0.0
到172.16.255.255
,共 1,048,576 个地址。192.168.0.0/16
:即从192.168.0.0
到192.168.255.255
,共 65,536 个地址。
包含在这个范围中的,都称为 私网IP
,其余的则称为公网 IP
(或全局 IP
)。
比如我们连接云服务器时,连接的这个 IP
地址就是云服务器的公网 IP
地址,而当我们在服务器终端使用 ifconfig
指令查看网卡信息的时候,看到的是此终端的私网 IP
地址!
2、我们为什么要给运营商交钱?
我们享受的是互联网公司提供服务,但为什么需要向运营商交钱呢?
- 实际 网络通信的基础设施都是运营商搭建的,我们访问服务器的数据并不是直接发送到了对应的服务器,而是需要经过运营商建设的各种基站以及各种路由器,最终数据才能到达对应的服务器。
- 因为运营商为我们提供了通信的基础设施,所以我们交网费实际就相当于购买入网许可一样。
- 没有运营商提供的这些基础设施,就不会诞生所谓的互联网公司,因为互联网公司是诞生在网络通信基础之上的。
也就是说,用户上网的数据首先必须经过运营商的相关网络设备,然后才能发送到互联网公司对应的服务器。因此 所谓的网段划分、子网划分等工作实际都是运营商做的。
3、数据是如何发送到服务器的
路由器是连接两个或多个网络的硬件设备,在路由器上有两种网络接口,分别是 LAN
口和 WAN
口:
LAN
口(Local Area Network
):表示 连接本地网络的端口,也就是对内服务,主要与家庭网络中的交换机、集线器或PC
相连。WAN
口(Wide Area Network
):表示==连接广域网的端口==,也就是对外服务,一般指互联网。
我们将 LAN
口的 IP
地址叫做 子网 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
)
4、为什么私网IP不能出现在公网当中?
- 不同的局域网中主机的
IP
地址可能是相同的,所以私网IP
无法唯一标识一台主机,因此不能让私网IP
出现在公网上,因为IP
地址要能唯一标识公网上的一台主机。 - 但由于
IP
地址不足的原因,我们不能让主机直接使用公网IP
而让主机使用私网IP
,因为私网IP
可以重复也就意味着我们可以在不同的局域网使用相同的IP
地址,缓解IP
的不足。 - 此外,我们不能直接使用公网
IP
还有一个原因就是,因为我们的 数据包必须要经过运营商的路由器,如果我们发送的数据直接到了公网,那也就意味着我们再也不用交网费了,这是不现实的。 - 并且直接暴露私网
IP
的话,遭到特定攻击的可能性就很大!
5、两个局域网当中的主机不能不跨公网进行通信
两个局域网当中的主机 理论上是不能不跨公网进行通信的,因为一个主机要将数据发送给另一台主机的前提是得先知道另一台主机的IP地址。
即便现在这个主机知道了另一台主机的 IP
地址,但 有可能这两台主机的 IP
地址是一样的,因为它们的 IP
地址都是私网 IP
地址。当这一台主机发送数据时将目的 IP
地址填成和自己相同的 IP
地址,操作系统就会认为这个数据就是要发给自己的,而不会向外进行发送了。
所以数据要从一个局域网发送到另一个局域网,如果不经过公网是基本上不可能的。我们在和别人聊天的时候,也不是直接将数据从一个局域网直接发送到了另一个局域网,而是先将数据经过公网发送到了服务器,然后再由服务器将数据经过公网转发到了另一个局域网。
但实际确实存在一些技术能够使数据包在发送过程中不进行公网 IP
的替换,而将数据正确送到目标主机,这种技术叫做 内网穿透,也叫做 NAT
穿透。