通信是互联网的基本功能,不管你是浏览网页,还是播放视频,或者下载软件,只要你使用计算机,就必然离不开网络。你能在手机、电脑上看到这篇文章,这本身就借助了网络。网络将你和别人的计算机连接在一起,构成了一张复杂的 Internet。
通信
图 1 网络通信
网络所要解决的问题只有一个,就是数据传输,包括:

  • 局域网内的数据传输,比如你将文件传输给公司内部的打印机;
  • 局域网和广域网的数据传输,比如你访问 C语言中文网、观看 B 站视频等;
  • 不同局域网之间的数据传输,比如你和异地恋的女朋友视频通话。

以上三种数据传输方式,复杂度依次递增,并且后面一种要依赖于前面一种。

这本 mini 电子书会从最简陋的网络开始讲起,然后逐步深入,直到讲明白最复杂的不同局域网之间的通信。

网线

两台计算机之间,只需要用一根网线把它们的网口(网线接口)连接起来,就能互相通信。
网线


图 2 一根网线连接两台计算机
我们知道,所有的数据在计算机中都是以二进制形式(0 和 1)存储的,两台计算机通信时传输的也是二进制数据。和电线类似,网线也是通过电流来传输数据的,并且通常用电压的高低来分别表示 0 和 1,从而将二进制数据传输给对方。

假设图 2 中的 A 向 B 发送数据,A 机器的网卡会将数据包转换成电信号,电信号通过网线就可以传送给 B 机器。B 机器的网卡接收到电信号后,会将其还原成二进制数据。

同样的道理,如果三台计算机各有两个网口,那么可以使用三根网线为它们建立通信,如下图所示:
网线


图 3 三根网线连接三台计算机
随着计算机的数量越来越多,除非每台计算机都预留出足够数量的网口,否则无法为它们全部建立通信。理论上讲计算机可以扩展出很多个网口,但实际我们使用的计算机只有一个网口,一些高端的计算机(服务器)可能会预留两个及以上的网口。

集线器

为多台计算机建立通信,人们想到的解决方法是:用网线将所有计算机和一台设备连接起来,此设备负责转发数据。例如:
集线器


图 4 集线器
如图 4 所示,所有计算机没有直接建立通信,而是全部连接到中间的这台设备上,称为集线器(简称 Hub)。

接收到数据包的集线器,会把数据包转发给网络中的其它计算机。比如上图中,集线器接收到 A 机器发送的数据包后,会将数据包转发给 B、C、D、E。也就是说,集线器并不能“精准”地转发数据,原本机器 A 只想和 B 通信,集线器却把数据包转发给网络中的所有机器,这就出现一个问题:各个结点接收到数据包后,如何判断是别人发送给自己的呢?

答案是 MAC 地址。每台计算机都有一个唯一的标识,叫作 MAC 地址。计算机出厂时,MAC 地址已经被写死到网卡里面了,每台计算机的 MAC 地址都是不一样的。

假设 A 机器的 MAC 地址为 aa-aa-aa-aa-aa-aa-aa,B 机器的 MAC 地址为 bb-bb-bb-bb-bb-bb。当 A 机器向 B 机器发送数据时,数据包中会同时附带 A 和 B 的 MAC 地址,如下图所示:
集线器


图 5 附带 MAC 地址的数据包
当 B 机器接收到数据包后,根据 MAC 信息就可以判定是发给自己的,于是收下数据。同样其它机器接收到数据包后,根据 MAC 信息判定不是发送给自己的,于是丢弃数据。下图演示了机器 A 向 B 发送数据的整个过程:
集线器


图 6 A发数据给B
和网线相比,集线器大大简化了计算机之间建立连接的复杂度,降低了硬件成本,计算机的数量越多,集线器的优势越明显。

当然集线器也有不足之处,比如:

  • 原本只发给一台计算机的数据,集线器会转发给网络内的所有计算机。这种情况下,如果有多台计算机同时向集线器发送数据包,数据的转发就会产生冲突(碰撞),严重时会导致数据传输失败;
  • 集线器“无脑地”将数据转发给所有机器,数据的安全性很难得到保证。例如,有些流氓软件和木马病毒会拦截发送给其它机器的数据包,窥探其它机器之间的通信。

    交换机

    集线器浪费网络资源,数据传输的速率也不高,逐渐淡出了市场,被一些高性能的设备所取代,比如交换机。
    交换机


图 7 交换机实现网络通信
上图演示的就是交换机传输数据的过程,它可以做到将数据包精准地转发给目标机器。

交换机拥有多个端口,每个端口都可以连接一台计算机。为了实现精准转发,交换机内部维护着一张表格,主要记录每台计算机的 MAC 地址和它占用的网口号,通常称为 MAC 地址表。

例如下图中的交换机有 6 个网口,连接着 4 台计算机,每台计算机的 MAC 地址和占用的网口号都记录在 MAC 地址表中:
交换机


图 8 交换机内部维护的表格
每当交换机接收到数据包后,通过内部维护的 MAC 地址表可以查出目标机器占用的网口号,进而将数据通过指定网口转发给目标机器。

初始状态下,交换机内部的 MAC 地址表是空的。下图中的机器 A 通过 4 号网口连接交换机,机器 B 通过 1 号网口连接交换机,图中演示了 MAC 地址表建立的过程:
交换机


图 9 MAC 地址表建立的过程
整个过程是:

  • 当机器 A 发送的数据包进入交换机后,交换机的 MAC 地址表中会记录下 A 的 MAC 地址和占用的网口号;
  • MAC 地址表没有和 B 相关的信息,因此交换机会像集线器那样将数据包转发给除 A 外的所有机器;
  • 机器 B 收到数据包后,确认数据是 A 发给自己的,于是收下数据并向 A 回传一份响应数据;
  • 响应数据包进入交换机后,交换机会记录下 B 的 MAC 地址和占用的网口号;
  • 通过查询 MAC 地址表,交换机会将响应数据包通过 4 号网口发送给 A。

随着网络中的机器相互通信,交换机内部的 MAC 地址表最终会建立完整。

基于交换数据包方式构建小型网络的技术称为以太网技术。以太网是一种组建网络的技术,该技术构建的小型网络称为局域网(LAN)。以太网是现阶段最常用的一种局域网技术。

一台交换机的网口数终究是有限的,随着计算机数量的增加,很可能要用多台交换机才能为所有机器建立通信,如下图所示:
交换机


图 10 多台交换机相互连接
图 10 中有两台交换机,它们内部维护的 MAC 地址分别是:

左侧交换机 右侧交换机
MAC地址 网口号 MAC地址 网口号
aa-aa-aa-aa-aa-aa 1 aa-aa-aa-aa-aa-aa 1
bb-bb-bb-bb-bb-bb 2 bb-bb-bb-bb-bb-bb 1
cc-cc-cc-cc-cc-cc 3 cc-cc-cc-cc-cc-cc 1
dd-dd-dd-dd-dd-dd 4 dd-dd-dd-dd-dd-dd 1
gg-gg-gg-gg-gg-gg 6 gg-gg-gg-gg-gg-gg 4
hh-hh-hh-hh-hh-hh 6 hh-hh-hh-hh-hh-hh 6
ee-ee-ee-ee-ee-ee 6 ee-ee-ee-ee-ee-ee 2
ff-ff-ff-ff-ff-ff 6 ff-ff-ff-ff-ff-ff 3

注意表格中标红的部分,交换机之间并非只记录一条信息,而是要记录对方网络中所有机器的信息。

路由器

为少量计算机搭建通信网络,交换机还是不错的选择,但如果是几万、几十万甚至更多的计算机,用交换机为它们构建局域网就会存在很多弊端,比如:

  • 网络中的每台交换机都需要维护大量的 MAC 地址,疲于应付;
  • 当网络中的计算机频繁通信时,很容易发生广播风暴,严重时会导致网络瘫痪。所谓广播风暴,指的是由于某些原因(网卡损坏、网络设备误用、网络病毒等)导致网络中存在大量无用的数据包,占用着大量的网络资源,正常的数据包也无法在网络中有效传送,网络设备也会因高负荷运转而受到影响。

路由器也是一种包含多个网口、能转发数据的设备,和交换机不同的是,路由器的每个网口都有独立的 MAC 地址。

例如下图中,两台交换机没有直接相连,而是连接到一台路由器上:
路由器


图 11 路由器连通两个局域网
路由器能有效缓解交换机对网络造成的影响:

  • 对于跨交换机发送数据的情况,交换机 A 的 MAC地址表中只需要记录 “路由器 MAC 地址 ABAB ~ 3号网口” 这条信息即可,而不需要记录 C、D 相关的信息。同样,交换机 2 也是如此。
  • 路由器可以缩小广播风暴的影响范围。比如交换机 1 所在的局域网发生广播风暴,不会影响交换机 2 所在的局域网。

交换机转发数据凭借的是 MAC 地址,而路由器转发数据凭借的是 IP 地址。IP 地址是 Internet Protocol Address 的缩写,译为“网际协议地址”。目前 IP 地址有两个版本,分别是 IPv4 和 IPv6 地址。

IPv4 本质是一个 32 位的二进制数,例如:

11000000101010000000000000000001

通常我们会将它等分为 4 份,中间用.分割,各部分再转换为十进制数:

11000000.10101000.00000000.00000001 <—> 192.168.0.1

从理论上讲,IPv4 地址一共有 232 - 1 ≈ 43 亿个,看似是一个很大的数字,但对于全世界 70 多亿人而言,IPv4 地址简直少得可怜。为了缓解 IPv4 资源枯竭的问题,人们设计了 NAT 技术(后续会讲),甚至提出用 IPv6 地址取代旧的 IPv4。IPv6 地址由 128 位二进制数组成,数量庞大到可以为地球上的每一粒沙子都分配一个 IPv6 地址。

其实早在 2021 年 IPv4 地址就已经枯竭了,凭借 NAT 技术才苦苦支撑到了今天。目前大部分软件仍在使用 IPv4 地址。IPv6 地址正在被人们接受,尤其是在教育网中已经大量使用。IPv6 将逐渐取代 IPv4,后者终有一天会埋没在历史的长河里。不过 IPv6 地址比 IPv4 复杂地多,接下来讲解网络知识仍使用 IPv4 地址(简称 IP 地址)。

局域网中的每台计算机既有唯一的 MAC 地址,也有唯一的 IP 地址;路由器的每个端口既有唯一的 MAC 地址,也有唯一的 IP 地址。MAC 地址一般是无法修改的,而 IP 地址可以手动修改。

为了方便讲解路由器转发数据的过程,我们先为图 11 中的设备添加上 IP 地址,如下图所示:
路由器


图 12 为计算机和路由器添加 IP 和 MAC 地址
路由器的存在,使得交换机的 MAC 地址表中不再需要记录网络中所有机器的信息,例如图中的交换机 1 就不需要记录 C、D 的信息。在这样的网络中传输数据,数据包中除了要携带 MAC 地址,还要携带 IP 地址。

比如图 12 中的机器 A 向 C 发送数据,传入路由器的数据包如下图所示:
路由器


图 13 机器 A 将数据发送给路由器
路由器发给机器 C 的数据包如下图所示:

路由器


图 14 路由器将数据发给 C
仔细观察两个数据包会发现,IP 部分是不变的,记录的一直都是源机器 A 和目标机器 C 的 IP 地址;MAC 地址是变化的,记录的分别是发送和接收数据包的设备。

接下来我们以图 12 中的机器 A 向 C 发送数据为例,通过讨论以下几个问题,帮大家梳理数据在网络中的传输过程。

1) A如何判断数据是否要发给路由器?

如果 A 向 B 发送数据,数据包可以直接经交换机转发给 B,不需要发送给路由器;如果 A 向 C 发送数据,A 必须先将数据包发送给路由器,再由路由器转发给 C。也就是说,不同的机器之间通信,有时需要将数据包发送给路由器,有时就不需要,那么机器是如何判别两种情况的呢?

答案是子网。要想搞清楚什么是子网,还需要对 IP 地址有深层次地了解。

类似我们的身份证号,每一段都具有不同的含义,IP 地址其实是由以下两部分构成的:

IP 地址 = 网络号 + 主机号

网络号和主机号一共是 32 位二进制数,它们各自占用的二进制位数不是固定的。

所谓子网,指的是一个局域网内所有 IP 网络号相同的机器组成的网络。例如图 12 的局域网内就包含两个子网:
子网


图 15 子网
子网 1 内所有机器的 IP 网络号都是 192.168.0,子网 2 内所有机器的 IP 网络号都是192.168.1

对于通信的两台机器,发送数据包之前要先判断它们是否同处一个子网,以此决定数据包是否由路由器转发。那么,网络中是如何划分子网的呢?答案是借助子网掩码。

和 IP 地址类似,子网掩码也是一个 32 位的二进制数,它是专门用来划分子网的。子网掩码从不单独存在,它只和 IP 地址搭配使用。

一台机器要想通信,必须同时具备 IP 地址和子网掩码。通过对 IP 地址和子网掩码做按位与运算,就可以轻松得到 IP 地址中的网络号,进而判断出它所处的子网。例如,我们为图 15 中的每台机器设置子网掩码为 255.255.255.0,如下图所示:
子网


图 16 子网掩码
如果 A 向 B 发送数据,首先将 A 和 B 的 IP 地址分别与 A 机器的子网掩码做按位与运算:

A 机器 IP & A 机器子网掩码:192.168.0.1 & 255.255.255.0 = 192.168.0.0 B 机器 IP & A 机器子网掩码:192.168.0.2 & 255.255.255.0 = 192.168.0.0

计算出的结果相同,表明 A 和 B 同处一个子网,A 机器会将数据包发给交换机 1,再由交换机转发给 B。

如果 A 向 C 发送数据,首先将 A 和 C 的 IP 地址分别与 A 机器的子网掩码做按位与运算:

A 机器 IP & A 机器子网掩码:192.168.0.1 & 255.255.255.0 = 192.168.0.0 C 机器 IP & A 机器子网掩码:192.168.1.1 & 255.255.255.0 = 192.168.1.0

计算出的结果不同,表明 A 和 C 处于不同的子网,A 机器会将数据包发给路由器,由路由器转发给 C。

注意,计算机的 IP 地址和子网掩码都是由 32 位二进制数组成的,理论上它们可以是0.0.0.0 ~ 255.255.255.255之间的任意一串数字,但事实并非如此。全世界需要联网的设备太多了,而 IP 地址的数量远远小于前者,为了合理分配 IP 地址,避免浪费,所有的 IP 地址被分为以下几类:

IP分类 地址范围 网络号位数 默认子网掩码 说 明
A 类 1.0.0.0~127.255.255.255 不能少于 8 位 255.0.0.0 此类 IP 地址默认前 8 位是网络号,例如申请一个 100.xxx.xxx.xxx 的 A 类地址,申请者可以自行决定后 24 位主机号的分配方式。A 类地址可以组建 127 个网络,每个网络中可以容纳 1 亿多台机器。
B 类 128.0.0.0~191.255.255.255 不能少于 16 位 255.255.0.0 此类 IP 地址默认前 16 位是网络号,例如申请一个 128.10.xxx.xxx 的 B 类地址,申请者可以自行决定后 16 位主机号的分配方式。B 类地址可以组建 16382 个网络,每个网络中可以包含 6 万多台机器。
C 类 192.0.0.0~223.255.255.255 不能少于 24 位 255.255.255.0 此类 IP 地址默认前 24 位是网络号,例如申请一个 192.10.10.xxx 的 C 类地址,申请者可以自行决定后 8 位主机号的分配方式。C 类地址可以组建多达 209 万个网络,但每个网络中最多包含 256 台机器。
D 类 224.0.0.0~239.255.255.255 有特殊用途。
E 类 240.0.0.0~255.255.255.255 留作将来使用。

各个 IP 分类中,在保证最低网络号位数的前提下,可以根据实际需求指定更多的二进制位作为网络号,从而可以组建更多数量的局域网。相应地,主机号的位数就会减少,网络中可容纳的机器个数会减少。

举个简单的例子,如果网络中的机器数量预计最多 100 台,那申请 C 类 IP 地址是最合适的,申请 A 和 B 类就会浪费大量的 IP 地址。

在图 16 的两个小型网络中,它们各自申请得到的是 192.168.1.xxx 和 192.168.0.xxx 这两个 C 类 IP 地址,使用的是默认子网掩码 255.255.255.0。每个小型网络中最多可以包含 256 台机器,必要时通过修改子网掩码,可以将 256 台机器划分成多个子网。

通常情况下,计算机会自动配置好 IP 地址和子网掩码,整个实现过程和 DHCP 协议有关。DHCP 全称动态主机配置协议,专门负责为局域网内的计算机分配 IP 地址和子网掩码。关于 DHCP 协议,大家简单了解即可,这里不再展开讲解。

2) 机器A怎样在网络中找到路由器?

当通信双方处于不同的子网时,源机器会将数据包发给路由器,再由路由器转发给目标机器。可是网络中的机器这么多,源机器是怎样找到路由器的呢?

答案是通过默认网关。默认网关(Default Gateway)又叫缺省网关,其实就是当前局域网中路由器的 IP 地址,网络中的每台计算机都必须记录这个地址。
路由器


图 17 默认网关
图 17 中 A 向 C 发送数据时,由于它们处于不同的子网(通过子网掩码判定),因此 A 会将数据包发送给以默认网关为 IP 地址的路由器。

3) 路由器怎样找到目标机器?

一台路由器有多个网口,每个网口都可以连接一个局域网。接收到数据包的路由器,必须先判定出目标机器所在局域网占用的网口号,才能将数据包转发出去。

仍以机器 A 向 C 发送数据为例,图 13 为 A 向路由器发送的数据包,包中记录的目标 MAC 地址是路由器的,只有 IP 地址是 C 的。路由器接收到数据包后,会从包中找到目标机器的 IP 地址,根据该地址判定出目标机器所在的局域网。

和交换机类似,路由器的内部也维护着一张表格,记录着各个网络占用的网口号,通常称为路由表。路由器中的路由表是通过一些算法建立的,比如向量-距离算法、链路-状态算法等,这里不再对这些算法展开介绍,只需要知道路由表是通过某些算法建立的,这就足够了。

例如,图 17 中路由器维护的路由表类似下面这样:

目标地址 子网掩码 下一跳地址 端口
192.168.0.0 255.255.255.0 0
192.168.0.254 255.255.255.255 0
192.168.1.0 255.255.255.0 1
192.168.1.254 255.255.255.255 1

通过将目标地址和子网掩码做按位与运算,就可以判定目标机器所处的子网。所谓下一跳地址,当网络中有多个路由器相连时,数据包可能途径多个路由器,这时才会用到下一跳地址,后面会通过一个实例讲解它。

很多书籍和教程中还喜欢这样表示路由表:

子网 下一跳地址 端口
192.168.0.0/24 0
192.168.0.254/32 0
192.168.1.0/24 1
192.168.1.254/32 1

/xx表示用 IP 地址中的前 xx 位二进制数为网络号,例如 192.168.0.0/24 指的是前 24 位二进制数为网络号,也就是 192.168.0。

通过路由表得知,子网 192.68.0.xxx 占用着路由器的 0 号网口,子网 192.168.1.xxx 占用着路由器的 1 号网口。仍以机器 A 向 C 发送数据,数据包的整个传送过程如下图所示:
路由


图 18 机器 A 向 C 发送数据的全过程
用文字描述一下数据包的整个传送过程:

  • A 向 C 发送数据,借助子网掩码判断出它们处于不同的子网,因此 A 会将数据发送给默认网关,也就是路由器。发送数据包之前,A 机器必须先通过 ARP 协议获得路由器的 MAC 地址并存入数据包中,才能将数据包发出;
  • 数据包首先经过交换机 1,根据数据包中的目标 MAC 地址,在 MAC 地址表中查到路由器 1 占用的网口,将数据包从该网口转发给路由器;
  • 接收到数据包的路由器会做两件事,首先是获取包中的目的 IP 地址,借助路由表查到机器 C 所在局域网占用的是 1 号网口;然后再通过 ARP 协议获得机器 C 的 MAC 地址并作为目的 MAC 地址更新到数据包中,最后将数据包从 1 号网口发出;
  • 交换机 2 接收到数据包后,根据数据包中的目的 MAC 地址,从 MAC 地址表查到机器 C 占用的网口号,于是从该网口将数据包发给 C;
  • 机器 C 收到数据包后,发现此数据确实是发给自己的,于是收下了数据。

整个过程中,大家比较困惑的应该只有 ARP 协议,无论 A 向路由器发送数据包,还是路由器将数据包转发给 C,都用到了这个协议。ARP(Address Resoloution Protocol)全称地址解析协议,专门根据目标机器的 IP 地址获取它的 MAC 地址。

我们知道,交换机是通过 MAC 地址传输数据的,但多数情况下,通信双方只知道对方的 IP 地址而不知道 MAC 地址。例如图 18 中 A 和 C 位于不同的子网,因此 A 必须先将数据包传输给默认网关,此时就只知道路由器的 IP 地址。这种情况下,借助 ARP 协议就可以找到对方的 MAC 地址。

简单理解 ARP 协议,同一局域网内的每台计算机(包括路由器)都维护着一张表格,用来记录其它机器 IP 地址和 MAC 地址的对应关系,通常称为 arp 表。

以图 18 中的机器 A 为例,起初维护的 arp 表是空的。为了知道路由器的 MAC 地址,A 会在局域网内发送一条 arp 请求,路由器接收到请求后会回传给 A 一条响应信息,信息中附带自己的 MAC 地址。收到响应信息后,机器 A 会将路由器的 IP 地址和 MAC 地址(192.168.0.254 : ABAB)存放在自己的 arp 表中,以便下次通信时使用。

关于路由表中的下一跳地址,通过一个实例了解它的用法:
路由表


图 19 机器A向F发送数据
图中有两个路由器相互连通,假设机器 A 向 F 发送数据,数据包要途径两个路由器后才能到达 F,这种情况下就需要用到路由表中的下一跳地址。以路由器 1 为例,路由表为:

子网 下一跳地址 端口
192.168.0.0/24 1
192.168.0.254/32 1
192.168.1.0/24 2
192.168.1.254/32 2
192.168.2.0/24 192.168.100.5
192.168.100.0/24 3
192.168.100.4/32 3

机器 A 向 F 发送数据的整个过程是:
1) 机器 A 的 IP 地址为 192.168.0.1,机器 F 的 IP 地址为 192.168.2.2。机器 A 的子网掩码为 255.255.255.0,分别和两个 IP 地址做按位与运算,计算出的结果不同,证明 A 和 F 位于不同的子网。因此机器 A 将数据包转发给默认网关,也就是路由器 1。

通过 ARP 协议获得路由器 1 的 MAC 地址是 ABAB,因此机器 A 发出的数据包为:
路由器


数据包会途径交换机 1,借助交换机内部的 MAC 地址表,可以查到路由器 1 占用着交换机的 3 号网口,交换机 1 会将数据包从 3 号网口转发给路由器 1。

2) 接收到数据包的路由器 1,从路由表中查找到目标 IP 对应的下一跳地址为 192.168.100.5。这种情况下,路由器 1 会做两件事:
①:再次去路由表中查找 192.168.100.5 所在子网对应的网口号,结果为 3 号;
②:借助 ARP 协议查找 192.168.100.5 对应的 MAC 地址,也就是路由器 2 的 MAC 地址 D2D2,然后更新数据包,如下图所示:
路由器


更新后的数据包会从 3 号网口转发给路由器 2。

3) 接收到数据包的路由器 2,从路由表查找目标 IP 所在子网占用的网口号(假设为 1 号网口)。

借助 ARP 协议找到 192.168.2.2 对应的 MAC 地址是 FFFF,然后更新数据包,如下图所示:
ARP


更新后的数据包会从路由器 2 的 1 号网口转发给机器 F。

数据包会途径交换机 3,通过在 MAC 地址查找目标 MAC 地址 FFFF 占用的是 6 号网口,交换机 3 会从 6 号网口将数据包转发给机器 F。

4) 最终,机器 F 收到了机器 A 发给它的数据包。

下图给大家演示了 A 向 F 发送数据的整个过程:
发送数据


图 20 机器 A 向 F 发送数据

因特网中的机器如何通信?

“网络”的定义是比较宽泛的,小到两台计算机之间的通信,大到世界上所有计算机之间的通信,都可以称为网络。根据地域覆盖范围的大小,可以将网络细分为以下三种:

  • 局域网(LAN):覆盖方圆几千米以内的网络,比如公司网络、家庭网络、网吧网络等;
  • 城域网(MAN):更大型的局域网,覆盖范围可以达到几十千米,数据传输的实现技术和局域网类似,比如覆盖一个城市的网络;
  • 广域网(WAN):覆盖地域最大,从几十千米到几万千米,可以覆盖一个或几个国家、一个或几个洲。因特网(互联网)就是典型的广域网。

    局域网和城域网、城域网和广域网之间没有明显的界限。

通过前面的讲解,我们已经清楚了局域网内的机器如何相互通信,接下来把网络范围扩大,看看因特网中的机器是如何通信的。

在同一个局域网内,任意两台机器的 IP 地址都不能相同,否则会发生 IP 地址冲突,导致两台机器都无法正常连通网络。但是在因特网里的多个局域网中,可能存在 IP 地址相同的多台机器,它们不仅不相互冲突,还能正常连网通信。

举个简单的例子,你和隔壁小伙伴在各自的家里上网,你的 IP 地址是 192.168.1.2,隔壁小伙伴的 IP 地址也是 192.168.1.2,甚至全世界有几百万台电脑的 IP 地址都是 192.168.1.2,这些设备不会相互冲突,都能上网通信。

前面提到 IPv4 地址是不够用的,为了缓解 IP 地址的分配压力,把 IP 地址分成了 A、B、C、D 和 E 共 5 类。不仅如此,A、B 和 C 类中还各自包含一些特殊的 IP 地址:

  • A 类:10.0.0.0 ~ 10.255.255.255
  • B 类:172.16.0.0 ~ 172.31.255.255
  • C 类:192.168.0.0 ~ 192.168.255.255

这些 IP 地址规定只允许在局域网内部使用,称为私网 IP 地址;相对地,其它 IP 地址称为公网 IP 地址。

私网 IP 和公网 IP 的区别有很多,比如:

  • 私网 IP 只能在局域网内部使用,在广域网中是不被承认的;公网 IP 在广域网使用。
  • 私网 IP 可以在不同的局域网内重复使用;公网 IP 在全世界是唯一的。
  • 私网 IP 的通信范围仅限在局域网内部;公网 IP 可以和因特网内的任意机器通信。
  • 公网 IP 由互联网服务提供商(简称 ISP,比如移动、电信、联通)分配,而私网 IP 地址由路由器分配。
  • 公网 IP 地址是收费的,而私网 IP 地址可以免费使用。

私网 IP 地址是无法用来在因特网上通信,这就引出一个问题,你和隔壁小伙伴使用的都是私网 IP 地址,为什么可以上网通信呢?

答案是利用 NAT 技术。NAT(Network Address Translation,网络地址转换)是一种将私网 IP 和公网 IP 相互转换的技术,通常实现在路由器上,称为 NAT 路由器。

NAT 路由器至少要分配 1 个公网 IP 地址,局域网内的机器要想和外网通信,必须先借助 NAT 技术将私网 IP 地址转换为公网 IP 地址;同样的道理,外网机器要想和局域网内的机器通信,也必须先借助 NAT 技术将公网 IP 地址转换为私网 IP 地址。

接下来,通过两个实例讲解因特网中机器通信的过程。

实例1:局域网机器访问外网服务器

假设本文发布在C语言中文网上,处于某个局域网内的你之所以能阅读本文,是因为你的浏览器向C语言中文网服务器发送了请求,随后服务器做出了响应并将文章数据回传给了你的浏览器。

需要注意的是,即便计算机有了 IP 地址和 MAC 地址,也仍然不能进行通信。原因很简单,一台计算机可以同时提供多种网络服务,比如 Web 服务(网站)、FTP 服务(文件传输服务)、SMTP 服务(邮箱服务)等,仅有 IP 地址和 MAC 地址,数据包虽然可以找到目标计算机,但目标机器不知道要将数据包交给哪个网络程序来处理,所以通信失败。

为了区分不同的网络程序,计算机会为每个网络程序分配一个独一无二的端口号(Port Number)。端口号是 0~65535 之间的十进制数,一些常见的端口号有:

  • Web 服务的端口号是 80;
  • FTP 服务的端口号是 21;
  • SMTP 服务的端口号是 25。

端口(Port)是一个虚拟的、逻辑上的概念。可以将端口理解为一道门,数据通过这道门流入流出,每道门有不同的编号,就是端口号。如下图所示:
端口


图 21 端口

前面在讲交换机和路由器的时候,虽然没有提及端口知识,但传输的数据包中也会记录通信双方的端口号,最终用端口号来确定将数据包发送给机器里的哪个网络程序。

在下图中,假设你使用机器 A 访问外网的 C 语言中文网服务器,服务器的端口是 80,机器 A 中想访问服务器的网络程序的端口是 1025。
端口


图 22 局域网内机器访问外网服务器
数据包在网络中的传输过程是:
1) C语言中文网的域名是 c.biancheng.net,通过 DNS 服务可以找到域名对应的 IP 地址,假设为 202.108.22.5。

DNS 是一种免费、快速、公共的互联网服务,它就像一个巨大的电话簿,记录着域名和 IP 的对应关系。如果你想访问某个网站,你需要先知道它的域名,然后通过 DNS 服务找到域名对应的 IP 地址;只有知道了 IP 地址,你才能将请求发送出去。

言外之意就是,网络通信是基于 IP 地址的,而不是基于域名的。域名只是一种助记符,IP 地址才是真正的“门牌号”。

你在浏览器中直接输入域名就能访问网站,是因为浏览器在后台帮助你完成了 DNS 转换过程。

2) 由于服务器的 IP 地址为 202.108.22.5,和机器 A 不在同一个子网,因此机器 A 会将请求数据包发送给默认网关(此过程会通过 ARP 获取到默认网关的 MAC 地址),也就是图中的 NAT 路由器。发送的数据包如下图所示:
端口


图 23 将数据包发送给默认网关
3) 接收到数据包的 NAT 路由器,会启动 NAT 技术将数据包中的源私网 IP 地址转换为公网 IP 地址,同时用一个新的端口号替换源端口号。NAT 路由器会将「源私网 IP + 端口号」和「公网 IP + 新端口号」的对应关系保存到一张表中,称为 NAT 转换表:

源私网 IP + 源端口号 公网 IP + 新端口号
192.168.1.2:1025 200.10.10.0:2222

图 23 的数据包经过 NAT 路由器加工后,会变成下图这样:
端口


图 24 NAT路由器发出的数据包
图中的下一跳指的是下一个路由器的 MAC 地址,数据在广域网中可能会经过多个路由器转发,过程中数据包的源 MAC 地址和目标 MAC 地址会不断变化,但源 IP 和目标 IP 是不变的。

4) 数据包经过多次转发,最终会到达C语言中文网的服务器。通过数据包中的目标 IP 地址和目标 MAC 地址,服务器确认数据包是发给自己的,于是收下数据并发送一个响应数据包。

5) 响应数据包在网络中的传送过程就是请求数据包的逆过程。起初的响应数据包如下图所示:
数据包


图 25 服务器发出的响应数据包
注意观察,数据包中的目标 IP 地址并不是机器 A 的,而是默认网关的,同样端口号也是如此。也就是说,对于服务器而言,它只知道是机器 A 的默认网关在和它通信,而不知道是机器 A。

6) 数据包在经过多个路由器转发后,最终会到达 NAT 路由器。NAT 路由器会启动 NAT 技术,根据 NAT 转换表将「目标 IP + 端口号」转换为「源私网 IP + 端口号」,再根据 arp 协议更新目标 MAC 地址,最终转发出去的数据包为:
数据包


图 26 局域网内的响应数据包
7) 剩下的工作就是在局域网内传输数据了,根据数据包中的目标 IP 和 MAC 地址,最终就能回传给机器 A。

实例2:不同局域网内的机器相互通信

通信
图 27 两个局域网内的机器相互通信
上图中有两个局域网,「A、B 和路由1」同属一个局域网,而「C、D 和路由2」同属另一个局域网。如果我们希望让 A 和 D 之间进行通信,该怎么做呢?

为了找到解决方案,我们必须首先明确一点:

公网(Internet)计算机无法直接向局域网内部的计算机传输数据,它必须先传输给 NAT 路由,然后再由 NAT 路由转发给局域网内部的计算机。

A 和 D 的通信要经过公网,这意味着:A 只能向 NAT 路由2传输数据,D 只能向 NAT 路由1传输数据。

但是,这个时候尴尬的问题出现了,就是我们不知道两台路由器的 IP 地址和端口号,通信失败!

拿到对方计算机的 IP 和端口号,是网络通信的前提。从某种角度来讲,网络通信就是向某个 IP 和端口号发送数据。

我们不妨思考一下【实例1】,C语言中文网服务器是如何知道 NAT 路由的 IP 和端口的呢?很简单,只要局域网内部的计算机访问一下服务器,服务器就能拿到 NAT 路由的 IP 地址和端口号(临时的)。

所以我们只要在公网中额外放置一台服务器,让 A 和 D 都访问这台服务器,然后获得 NAT 路由的 IP 和端口号,就能让 A 和 D 之间进行通信了。

你看,绕来绕去,不同局域网中的计算机并不能直接通信,必须要有一台公网服务器牵线搭桥,让它们之间“勾搭”上。只有“勾搭”完了以后,它们之间就能直接发送数据了,就不需要公网服务器了。

你和异地恋的女友之所以能 QQ 视频,是因为你们在登录 QQ 时都会访问腾讯的服务器,服务器会记录你们的 NAT 路由信息,当你们之间想发起视频时,服务器只需要告知对方的 NAT 路由信息就可以了。

最后,我们再来梳理一下通信细节。假设访问公网服务器以后,A 和 D 的 NAT 路由信息如下所示:
表:路由 1 的NAT转换表

源私网 IP + 源端口号 公网 IP + 新端口号
192.168.1.2:1025 200.10.10.0:2222

表:路由 2 的NAT转换表

源私网 IP + 源端口号 公网 IP + 新端口号
192.168.1.4:1025 200.20.20.0:3333

我们以 A 向 D 发送数据包为例,数据包在网络中的传输过程是:

  1. A 将数据包发送给 D 的默认网关,也就是路由 2。数据包中的目标 IP 地址为 200.20.20.0,端口号为 3333。
  2. 数据包经过路由 1 时,数据包中的源 IP 地址和端口号被分别转换为 200.10.10.0 和 2222;
  3. 经过因特网中多个路由器的转发,数据包最终会到达路由 2;
  4. 路由 2 根据数据包中记录的目标 IP 地址和端口号,判断数据包确实是发送给当前局域网内某台机器的,于是收下数据包并根据 NAT 转换表将包中的目标 IP 地址和端口号分别转换为 192.168.1.4 和 1025;
  5. 数据包达到 D 所在的局域网内部后,根据 IP 地址和 MAC 地址就可以找到机器 D。

反过来,D 向 A 发送数据包也是类似的流程。

在实际场景中,为不同局域网内的机器建立通信的过程可能更加复杂,感兴趣的读者可以自行研究 NAT内网穿透技术。

总结

本文分别从网线直连(包括集线器)、交换机和路由器的角度讲解了数据在网络中的传输细节,接下来再给大家从计算机、交换机和路由器的视角总结一下。

计算机视角:

  • 必须知道目标机器的 IP 地址和端口号。当通信双方位于不同的局域网时,需要借助第三方服务器得知对方默认网关的 IP 地址和端口号;
  • 借助子网掩码,判定是否和对方同处一个子网:
    • 若同处一个子网,通过 ARP 协议直接获得对方的 MAC 地址,数据包通过交换机转发给对方;
    • 若位于不同的子网,通过 ARP 协议获得当前局域网中默认网关的 MAC 地址,数据包通过默认网关转发给对方。

交换机视角:

  • 接收到的数据包必须包含目标机器的 MAC 地址;
  • 在 MAC 地址表中查询目标机器占用的网口号,若查询成功,直接将数据包通过指定网口发送给目标机器;若查询失败,将数据包从所有网口发送出去。

路由器视角:

  • 接收到的数据包必须包含目标机器的 IP 地址;
  • 借助路由表中记录的信息,要么找到目标机器所在子网占用的网口号,将数据包通过该网口转发出去,要么找到目标机器 IP 地址对应的下一跳地址,将数据包转发到下一个路由器。

    【扩展】OSI 和 TCP/IP 模型

    如果你读过计算机专业,或者学习过网络通信,一定听说过 OSI 模型,它曾无数次让你头大。OSI 是 Open System Interconnection 的缩写,译为“开放式系统互联”。

OSI 模型把网络通信的工作分为 7 层,从下到上分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,如下图所示:
OSI 模型


图 28 OSI模型和 TCP/IP 模型
实际上,本节讲到的数据包借助网线(集线器)、交换机和路由器传输的过程,就分别对应 OSI 模型的物理层、数据链路层和网络层,每一层各司其职,相互配合,共同完成网络通信。网线和集线器属于实现物理层功能的设备,交换机是一种实现数据链路层功能的设备,路由器是一种实现网络层功能的设备。

在 OSI 模型中,真正负责实现网络通信的是下三层。

OSI 只是存在于概念和理论上的一种模型,它的缺点是分层太多,增加了网络工作的复杂性,所以没有大规模应用。后来人们对 OSI 进行了简化,合并了一些层,最终只保留了 4 层,从下到上分别是接口层、网络层、传输层和应用层,这就是大名鼎鼎的 TCP/IP 模型。