Pre
广域网是由很多的局域网组成的,比如公司网络、家庭网络、校园网络等。之前我们一直在讨论广域网的设计,今天我们到微观层面,看看局域网是如何工作的。
IPv4 的地址不够,因此需要设计子网。当一个公司申请得到一个公网 IP 后,会在自己的公司内部设计一个局域网。这个局域网所有设备的 IP 地址,通常会以 192.168 开头。
这个时候,假设小明,上班时间玩王者荣耀。当他用 UDP 协议向王者荣耀的服务器发送信息时,消息的源 IP 地址是一个内网 IP 地址,而王者荣耀的服务,是一个外网 IP 地址。
先提一个问题,数据到王者荣耀服务器可以通过寻址和路由找到目的地,但是数据从王者荣耀服务器回来的时候,王者荣耀服务器如何知道192.168开头的地址应该如何寻址呢?
要想回答这个问题,就涉及网络地址转换协议(NAT 协议)。
内部网络和外部网络
对一个组织、机构、家庭来说,我们通常把内部网络称为局域网,外部网络就叫作外网。下图是一个公司多个部门的网络架构。
我们会看到外网通过路由器接入整个公司的局域网,和路由器关联的是三台交换机,代表公司的三个部门。 交换机,或者称为链路层交换机,通常工作在链路层;而路由器通常也具有交换机的能力,工作在网络层和链路层 。
光纤是一种透明的导光介质,多束光可以在一个介质中并行传播,不仅信号容量大,重量轻,并行度高而且传播距离远。当然,光纤不能弯曲,因此办公室里用来连接交换机和个人电脑的线路肯定不能是光纤, 光线通常都用于主干网络 。
局域网数据交换(MAC 地址)
接下来我们讨论下同一个局域网中的设备如何交换消息。
首先,我们先明确一个概念,设备间通信的本质其实是设备拥有的网络接口(网卡)间的通信**。为了区别每个网络接口,互联网工程任务组(IETF)要求每个设备拥有一个唯一的编号,这个就是 MAC 地址**。
你可能会问:IP 地址不也是唯一的吗?其实不然,一旦设备更换位置,比如你把你的电脑从北京邮寄的广州,那么 IP 地址就变了,而电脑网卡的 MAC 地址不会发生变化。总的来说,IP 地址更像现实生活中的地址,而 MAC 地址更像你的身份证号。
然后,我们再明确另一个基本的概念。 在一个局域网中,我们不可以将消息从一个接口(网卡)发送到另一个接口(网卡),而是要通过交换机 。为什么是这样呢?因为两个网卡间没有线啊!所以数据交换,必须经过交换机,毕竟线路都是由网卡连接交换机的。
总结下,数据的发送方,将自己的 MAC 地址、目的地 MAC 地址,以及数据作为一个分组(Packet),也称作 Frame 或者封包,发送给交换机。交换机再根据目的地 MAC 地址,将数据转发到目的地的网络接口(网卡) 。
最后一个问题,你可能问,这个分组或者 Frame,是不是 IP 协议的分组呢?——不是,这里提到的是链路层的数据交换,它支持 IP 协议工作,是网络层的底层。所以,如果 IP 协议要传输数据,就要将数据转换成为链路层的分组,然后才可以在链路层传输。
链路层分组大小受限于链路层的网络设备、线路以及使用了链路层协议的设计。你有时候可能会看到 MTU 这个缩写词,它指的是 Maximun Transmission Unit,最大传输单元 , 意思是链路层网络允许的最大传输数据分组的大小。因此 IP 协议要根据 MTU 拆分封包 。
介绍 TCP 协议滑动窗口的时候,还提到过一个词,叫作 MSS,这里我们复习下。MSS(Maximun Segment Size,最大段大小)是 TCP 段,或者称为 TCP 分组(TCP Packet)的最大大小。 MSS 是传输层概念,MTU 是链路层概念
聪明的同学可以能会意识到,这不就是下面这样一个数学关系吗?
MTU = MSS + TCP Header + IP Header
这个思路有一定道理,但是不对 。先说说这个思路怎么来的,你可能会这么思考:TCP 传输数据大于 MSS,就拆包。每个封包加上 TCP Header ,之后经过 IP 协议,再加上 IP Header。于是这个加上 IP 头的分组(Packet)不能超过 MTU。固然这个思路很有道理,可惜是错的。 因为 TCP 解决的是广域网的问题,MTU 是一个链路层的概念,要知道不同网络 MTU 是不同的,所以二者不可能产生关联。这也是为什么 IP 协议还可能会再拆包的原因 。
地址解析协议(ARP)
上面我们讨论了 MAC 地址,链路层通过 MAC 地址定位网络接口(网卡)。在一个网络接口向另一个网络接口发送数据的时候,至少要提供这样 3 个字段:
- 源 MAC 地址
- 目标 MAC 地址
- 数据
这里我们一起再来思考一个问题, 对于一个网络接口,它如何能知道目标接口的 MAC 地址呢 ?我们在使用传输层协议的时候,清楚地知道目的地的 IP 地址,但是我们不知道 MAC 地址。这个时候,就 需要一个中间服务帮助根据 IP 地址找到 MAC 地址——这就是地址解析协议(Address Resolution Protocol,ARP) 。
整个工作过程和 DNS 非常类似,如果一个网络接口已经知道目标 IP 地址对应的 MAC 地址了,它会将数据直接发送给交换机,交换机将数据转发给目的地,这个过程如下图所示:
那么如果网络接口不知道目的地地址呢?这个时候,地址解析协议就开始工作了。发送接口会发送一个广播查询给到交换机,交换机将查询转发给所有接口。
如果某个接口发现自己就是对方要查询的接口,则会将自己的 MAC 地址回传。接下来,会在交换机和发送接口的 ARP 表中,增加一个缓存条目。也就是说,接下来发送接口再次向 IP 地址 2.2.2.2 发送数据时,不需要再广播一次查询了。
前面提到这个过程和 DNS 非常相似,采用的是逐级缓存的设计减少 ARP 请求 。发送接口先查询本地的 ARP 表,如果本地没有数据,然后广播 ARP 查询。这个时候如果交换机中有数据,那么查询交换机的 ARP 表;如果交换机中没有数据,才去广播消息给其他接口。 注意,ARP 表是一种缓存,也要考虑缓存的设计 。通常缓存的设计要考虑缓存的失效时间、更新策略、数据结构等。
比如可以考虑用 TTL(Time To Live)的设计,为每个缓存条目增加一个失效时间。另外,更新策略可以考虑利用老化(Aging)算法模拟 LRU。
最后请你思考路由器和交换机的异同点。不知道你有没有在网上订购过家用无线路由器,通常这种家用设备也会提供局域网,具备交换机的能力。同时,这种设备又具有路由器的能力。所以,很多同学可能会分不清路由器和交换机。
总的来说,家用的路由器,也具备交换机的功能。但是当 ARP 表很大的时候,就需要专门的、能够承载大量网络接口的交换设备。就好比,如果用数组实现 ARP 表,数据量小的时候,遍历即可;但如果数据量大的话,就需要设计更高效的查询结构和设计缓存。
连接内网
有时候,公司内部有多个子网。这个时候一个子网如果要访问另一个子网,就需要通过路由器。
也就是说,图中的路由器,其实充当了两个子网通信的桥梁。在上述过程中,发送接口不能直接通过 MAC 地址发送数据到接收接口,因为子网 1 的交换机不知道子网 2 的接口。这个时候,发送接口需要通过 IP 协议,将数据发送到路由器,再由路由器转发信息到子网 2 的交换机。这里提一个问题, 子网 2 的交换机如何根据 IP 地址找到接收接口呢?答案是通过查询 ARP 表 。
连接外网(网络地址转换技术,NAT)
最后我们讨论下连接外网的问题。
IPv4 协议因为存在网络地址耗尽的问题,不能为一个公司提供足够的地址,因此内网 IP 可能会和外网重复。比如内网 IP 地址192.168.0.1发送信息给22.22.22.22,这个时候,其实是跨着网络的。
跨网络必然会通过多次路由,最终将消息转发到目的地。但是这里存在一个问题,寻找的目标 IP 地址22.22.22.22是一个公网 IP,可以通过正常的寻址 + 路由算法定位。当22.22.22.22寻找192.168.0.1的时候,是寻找一个私网 IP,这个时候是找不到的。解决方案就是网络地址转换技术(Network Address Translation)。
NAT 技术转换的是 IP 地址,私有 IP 通过 NAT 转换为公网 IP 发送到服务器。服务器的响应,通过 NAT 转换为私有 IP,返回给客户端。通过这种方式,就解决了内网和外网的通信问题 。
总结
总结一下,链路层发送数据靠的是 MAC 地址,MAC 地址就好像人的身份证一样。局域网中,数据不可能从一个终端直达另一个终端,而是必须经过交换机交换。
交换机也叫作链路层交换机,它的工作就是不断接收数据,然后转发数据。通常意义上,交换机不具有路由功能,路由器往往具有交换功能。但是往往路由器交换的效率,不如交换机。
已知 IP 地址,找到 MAC 地址的协议,叫作地址解析协议(ARP)。
网络和网络的衔接,必须有路由器(或者等价的设备)。一个网络的设备不能直接发送链路层分组给另一个网络的设备,而是需要通过 IP 协议让路由器转发。
QA
网络地址转换协议是如何工作的?
网络地址解析协议(NAT)解决的是内外网通信的问题。NAT 通常发生在内网和外网衔接的路由器中,由路由器中的 NAT 模块提供网络地址转换能力。从设计上看,NAT 最核心的能力,就是能够将内网中某个 IP 地址映射到外网 IP,然后再把数据发送给外网的服务器。当服务器返回数据的时候,NAT 又能够准确地判断外网服务器的数据返回给哪个内网 IP。
可以思考下 NAT 是如何做到这点的呢?需要做两件事。
NAT 需要作为一个中间层替换 IP 地址。 发送的时候,NAT 替换源 IP 地址(也就是将内网 IP 替换为出口 IP);接收的时候,NAT 替换目标 IP 地址(也就是将出口 IP 替换回内网 IP 地址)。
NAT 需要缓存内网 IP 地址和出口 IP 地址 + 端口的对应关系。也就是说,发送的时候,NAT 要为每个替换的内网 IP 地址分配不同的端口,确保出口 IP 地址+ 端口的唯一性,这样当服务器返回数据的时候,就可以根据出口 IP 地址 + 端口找到内网 IP。
IPv6 协议还需要 NAT 吗?
IPv6 解决了 IP 耗尽的问题,为机构、组织、公司、家庭等网络提供了充足的 IP 资源,从这个角度看是不是就不需要 NAT 协议了呢?
在没有 IPv6 之前,NAT 是 IP 资源耗尽的主流解决方案。在一个内网中的全部设备通过 NAT 协议共 享一个外网的 IPv4 地址,是目前内外网对接的主要方式。IPv6 地址资源充足,可以给全球每个设备一个独立的地址。从这个角度看 IPv6 的确不需要 NAT 协议。
但是目前的情况,是 IPv6 网络还没有完全普及。尽管很多公司已经支持自己的互联网产品可以使用 IPv6 访问,但是公司内部员工使用的内部网络还是 IPv4。如果要连接 IPv6 和 IPv4 网络,仍然需要 NAT 协议(NAT64),这个协议可以让多个 IPv6 的设备共享一个 IPv4 的公网地址。
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。