局域网
子网与子网掩码
网络上,数据从一个地方传到另外一个地方,是依靠 IP 寻址。从逻辑上来讲,是两步的。
第一步,从 IP 中找到所属的网络,好比是去找这个人是哪个小区的;
第二步,再从 IP 中找到主机在这个网络中的位置,好比是在小区里面找到这个人。
第一步中的网络,就称之为「子网」(Subnet)。从逻辑上来讲,一般同一子网(Subnet)是使用相同的网关。就好比,一个小区的入口。
IPv4 的 IP 地址是 32 位的,形式如 http://xxx.xxx.xxx.xxx,每一个 xxx 取值都是 0 - 255。到底是前三个 xxx 相同,就代表同一个子网,还是前两个,还是其他?这个并不一定。就好比小区有大有小,有的小区有上千户人家,有的小区只有区区几个。所以,就引入子网掩码
(Subnet Mask)来标识该子网的大小。
我们一般看到的 IP 地址是十进制的编码,所以如果换一个视角,从二进制的角度看,每一个 IP 地址就是 32 位 1 或 0。子网掩码,就是用来告诉这个子网的覆盖区间。这 32 位中,前多少位是网络段?当然,余下的就是主机段。
举典型的例子:IP 中前 24 位代表子网号,后 8 位代表主机号。所以子网掩码就是 24 个 1(代表前 24 位是子网部分),加 8 个 0(后 8 位是主机部分)。如果沿用 IP 的标识方式,就是 255.255.255.0 。每一个 255 对应 8 个二进制 1,最后一个 0 对应 8 个二进制 0。该子网可以容纳最多 256 台主机,也就是主机号从 0 到 255。当然,实际情况没有这么多,有一些特殊数字有保留用处(广播、网关等)。
网关
大家都知道,从一个房间走到另一个房间,必然要经过一扇门。同样,从一个网络向另一个网络发送信息,也必须经过一道“关口”,这道关口就是网关。
什么是网关
顾名思义,网关(Gateway)就是一个网络连接到另一个网络的“关口”。
按照不同的分类标准,网关也有很多种。TCP/IP协议里的网关是最常用的,在这里我们所讲的“网关”均指TCP/IP协议下的网关。
那么网关到底是什么呢?网关实质上是一个网络通向其他网络的IP地址。比如有网络A和网络B,网络A的IP地址范围为“192.168.1.1~192. 168.1.254”,子网掩码为255.255.255.0;网络B的IP地址范围为“192.168.2.1~192.168.2.254”,子网掩码为255.255.255.0。在没有路由器的情况下,两个网络之间是不能进行TCP/IP通信的,即使是两个网络连接在同一台交换机(或集线器)上,TCP/IP协议也会根据子网掩码(255.255.255.0)判定两个网络中的主机处在不同的网络里。而要实现这两个网络之间的通信,则必须通过网关。如果网络A中的主机发现数据包的目的主机不在本地网络中,就把数据包转发给它自己的网关,再由网关转发给网络B的网关,网络B的网关再转发给网络B的某个主机。网络B向网络A转发数据包的过程也是如此。
所以说,只有设置好网关的IP地址,TCP/IP协议才能实现不同网络之间的相互通信。那么这个IP地址是哪台机器的IP地址呢?网关的IP地址是具有路由功能的设备的IP地址,具有路由功能的设备有路由器、启用了路由协议的服务器(实质上相当于一台路由器)、代理服务器(也相当于一台路由器)。
通信举例
术语:
- 数据包(packet):IP 协议传送数据的单位;
- 帧(frame):链路层传送数据的单位;
- 节点(node):实现了 IP 协议的设备;
- 路由器(router):可以转发不是发给自己的 IP 包的设备;
- 主机(host):不是路由器的节点;
- 链路(link):一种通信机制或介质,节点可以通过它在链路层通信,比如以太网、PPP 链接,也包括隧道;
- 接口(interface):节点与链路的连接(可以理解为抽象的“网卡”);
- 链路层地址(link-layer address):接口的链路层标识符(如以太网的 mac 地址);
以太网络中包的转发
要想讲清楚这个问题,我们要从 IP 的工作过程说起。来看网络拓扑:
1 |
|
我们现在考虑这样的一个网络,这个网络中有两个链路(介质是以太网),分别是 192.0.2.0/24 和 203.0.113.0/24。两个链路中各有一个主机,接口的地址分别是 192.0.2.3 与 203.0.113.4,子网掩码都是 /24。有一个路由器 R,有两个接口,分别与这两个链路相连,地址分别是 192.0.2.1 和 203.0.113.1 ,子网掩码都是 /24。A 和 B 都把 R 作为自己的默认网关。
今 A 要给 B 发送一个数据包。按照 IP 协议的工作过程,发生的事情应该是这样的:
- A 生成一个数据包,目的地址填 203.0.113.4,源地址填 192.0.2.3;
- A 查本机路由表,匹配默认路由,选定下一跳 192.0.2.1 和相应出接口;
- A 将包发出;
- R 收到该数据包,查 R 的路由表,匹配链路本地路由 203.0.113.0/24,出接口 en1;
- R 处理该数据包(TTL 减一,重算 checksum),然后从 en1 发出;
- B 收到该数据包,并处理。
看起来没什么问题,很简单。但是你会注意到,这个 “下一跳”,似乎和数据包的内容没什么关系。你应该能察觉到我在什么地方故意遗漏了些东西。
其实,这里出问题的地方就是 “A 将包发出, R 收到该数据包” 的过程。如果要刨根问底,我们就要搞清楚 A 是怎么发出的数据包,R 是怎么收到的。
众所周知,IP 工作在第三层,要想发送数据,数据必须要委托给第二层——链路层来发送。我们这里的链路层是以太网。在以太网上,数据以帧为单位进行传送。也就是说,这个数据包要被包装为一个帧,从 A 发给了 R。
问题来了,以太网上传输的帧需要源 MAC 地址和目的 MAC 地址。这里的源 MAC 地址,显然是 A 的 MAC 地址,但是目的 MAC 地址是什么呢?稍加思考,你就会知道,肯定是 R 的 en0 的 MAC 地址。而 A 是怎么知道 R 的 en0 的 MAC 地址呢?这时,下一跳地址闪亮登场。A 之所以能知道 R 的 en0 的 MAC 地址,是因为 A 在路由查找的时候,确定了“下一跳地址”和出接口,然后,它在出接口的链路上通过 ARP 的方式,解析这个“下一跳地址”对应的 MAC 地址。
一般地,任何一个节点在发送(转发或直接发送)数据包的时候,都会查本机路由表,确定出接口和下一跳地址(如果有),而结果往往分两种情况:
-
目的 IP 地址是 On-link,即查到的路由是链路本地路由(如 R 将数据包发送给 B 的过程)。那么直接在出接口所在链路上,使用目的 IP 地址,作地址解析,得到链路地址,将其发出。
-
目的 IP 地址是 Off-link,即查到的路由有下一跳地址。那么此时,在出接口链路上,使用下一跳地址作地址解析,得到链路地址,将其发出。