网络是如何连接的:中继、集线器、交换机与网桥
之前一直对二层网络连接的知识体系模模糊糊,最近有空就总结了下。
这篇主要区分了一下常见的网络设备:
graph TB a(中继) b(集线器) c(网桥) d(交换机) e(网关) f(路由器) %%
上述设备工作的 OSI 网络层次分别是:
graph TB L5(应用层/表示层/会话层) L4(传输层) L3(网络层) L2(数据链路层) L1(物理层) H1([网卡,中继,集线器]) H2([网桥,交换机]) H3([路由器,网关]) subgraph OSI网络模型 L5 --> L4 --> L3 --> L2 --> L1 end H1 -.-> L1 H2 -.-> L2 H3 -.-> L3 classDef comment fill:#fff,stroke:gray,stroke-dasharray: 5 5 class H1,H2,H3 comment %%
中继器 Repeater
为什么要有中继器?
当只有两台设备需要互相通信时,我们可以仅使用网线将设备连接起来。当两台需要通信的设备物理间隔比较远时,由于信号的衰减,我们就需要中继器来放大信号,使得信号传的更远。
- 理论上只有一进一出两个端口,将进入端口的信号转发至另一个端口。
- 单纯的信号放大装置,用来扩大信号的传输距离。
- 典型的例子是:家里 WIFI 信号不够好时,可以通过增加中继器或把额外的路由器设置为中继模式来扩展 WIFI 覆盖范围。
下面两中拓扑结构的最终效果是等价的:
flowchart LR c1(A fas:fa-desktop) o--o h1(fas:fa-bolt 中继器) o--o c2(B fas:fa-desktop) c3(A fas:fa-desktop) o---o c4(B fas:fa-desktop) %%
中继器没有做到的事情:
中继器解决了远距离传播信号的问题。但是现实中我们不会仅仅只需两台设备互相通信,而是多台设备都能互相通信,这种情况下我们就需要更高级的设备了。
集线器 Hub
中继器解决了两台设备远距离通信的问题,但是当多台设备需要互相通信时,需要在任意两台设备之间连接一条网线,网络拓扑是这样的:
flowchart LR c1(A fas:fa-desktop) c2(B fas:fa-desktop) c3(C fas:fa-desktop) c1 --- c2 c1 --- c3 c2 --- c3 %%
网络中每增加一台设备,主机 A 就增加一条网线,这显然是现实的。为了解决这个问题,集线器被发明了。
集线器用最简单的方式解决了多台设备互相通信的问题。具体的做法是:集线器有多个端口,可以连接多个设备(如下图)。当一台设备发送了数据帧,集线器会将这个数据帧转发至其他左右的端口。
下图是一个集线器构成的网络拓扑,A 发送了一个数据帧给 C,这个数据先被集线器收到:
flowchart LR c1(A fas:fa-desktop) h1(fas:fa-boxes 集线器) c2(B fas:fa-desktop) c3(C fas:fa-desktop) c4(D fas:fa-desktop) c1 --> | 给 C 的消息 | h1 h1 --- c2 h1 --- c3 h1 --- c4 %%
集线器将消息发送至除 A 外的每一台设备:
flowchart LR c1(A fas:fa-desktop) h1(fas:fa-boxes 集线器) c2(B fas:fa-desktop) c3(C fas:fa-desktop) c4(D fas:fa-desktop) c1 --- h1 h1 --> | 给 C 的消息 | c2 h1 --> | 给 C 的消息 | c3 h1 --> | 给 C 的消息 | c4 %%
之后 B、D 会将不需要的消息丢弃掉,C 收到的消息会被正常处理。这个过程中 B、D 两个设备的带宽就被浪费掉了。
由于使用集线器的通讯方式是广播通信(数据会发给每一个连接到集线器的设备),因此还会有一定的安全隐患。
总结集线器:
- 有多个端口,可以连接多台终端,让彼此存在互相通信的可能。
- 将一个端口的信号转发至其他所有的端口。
- 可以看成一个多端口的中继器。
- 缺陷
- 网络规模较小。
- 集线器的最大问题是多设备共享带宽。因为集线器同一个时刻仅能够执行一个收 / 发任务,所以网络拓扑中的设备越多,每台设备分到的带宽就越小,限制了网络的扩展。
- 数据帧以广播的方式发送(会发送到每台设备上),有信息泄漏的风险。
网桥 Bridge
为了解决集线器构成的网络拓扑中规模较小的问题,网桥被发明出来了。
- 至少有两端口。
- 集线器会对每个端口维护一个 MAC 地址列表。当某个端口连接的是主机时,记录的 MAC 地址就是该主机的 MAC 地址;当连接的是集线器时,记录的 MAC 地址就是集线器上连接的所有主机的 MAC 地址。
- 当网桥收到主机 / 集线器发来的数据帧时,会对比数据帧中的目的 MAC 地址,如果该地址不再对应端口的 MAC 地址表中,才会向另一个端口转发该数据帧。
- 相比于集线器连接的网络,可以减少无效的转发,提高效率。
其网络拓扑如下 (以两个端口的网桥为例):
flowchart LR c1(A fas:fa-desktop) c2(B fas:fa-desktop) c3(C fas:fa-desktop) c4(D fas:fa-desktop) c5(E fas:fa-desktop) c6(F fas:fa-desktop) c7(G fas:fa-desktop) c8(H fas:fa-desktop) h1(fas:fa-boxes 集线器 A) h2(fas:fa-boxes 集线器 B) b1(fas:fa-network-wired 网桥) c1 --- h1 c2 --- h1 c3 --- h1 c4 --- h1 h1 --- b1 --- h2 h2 --- c5 h2 --- c6 h2 --- c7 h2 --- c8 com2(端口2:\nmacE,\nmacF,\nmacG,\nmacH,) com1(端口1:\nmacA,\nmacB,\nmacC,\nmacD,) com1 -.- b1 b1 -.- com2 classDef comment fill:#fff,stroke:gray,stroke-dasharray: 5 5 class com1,com2 comment %%
如图上:
- 当 A 向 F 发送数据帧
AtoF
。AtoF
会现被 A 发送 集线器 A。- 集线器 A 将
AtoF
发送到网桥(此时集线器 A 连接的是网桥的端口 1)。 - 网桥查看 F 是否在端口 1 对应的 MAC 表中存在:
- 存在:网桥会丢弃该数据帧;
- 不存在;接下来查找其他端口的 MAC 表,看 F 是否在某个表中存在:
- 存在:从这个端口中转发该数据帧。
- 不存在:则将
AtoF
从端口 1 以外的所有端口发送出去。(泛洪)
- 集线器 B 会将
AtoF
转发到 F 上,通信完成。
- 另一种情况,当 B 向 D 发送数据帧:
BtoD
。BtoD
会现被 B 发送 集线器 A。- 集线器 A 将
BtoD
发送到网桥。 - 网桥会对查看端口 1 对应的 MAC 地址表,D 的地址在 MAC 地址表中,则网桥不做转发。
网桥的 mac 地址表是怎么建立起来的?
还是以上面的过程为例:
- 当网桥刚刚开机,两个端口对应的 mac 地址表都为空。
- 假设网桥从端口 1 中收到一个 AtoE 发出来的数据帧,此时网桥会执行两个动作:
- 查看 E 的 MAC 地址时都在端口 1 的 MAC 表中;不在,于是向端口 2 转发该数据帧
- 取得数据帧中的源 MAC 地址(即 A),将其加入到端口 1 的地址表中。
- 假设此时网桥又从端口 1 收到一个 BtoA 的数据帧:
- 比对目的地址 A 是否在对应的地址表中;在,于是丢弃该数据帧,不做转发
- 将源地址 B 加入端口 1 的 MAC 地址表中。
- 下次再有目的地址是 A 或者 B 的数据帧从端口 1 到达时,网桥就知道不应该转发该数据帧了。
网桥建立的网络拓扑存在的缺陷
相对于集线器,网桥极大的减少了广播数据,使得数据帧被限制在较小的范围内。同时提高了带宽的利用率。但是网桥并不是完美的。
- 当 MAC 地址表为空时,网桥会转发收到的数据帧,使得该数据帧在网桥连接的网络上扩散,最终每台设备机器都会收到这个数据帧。
- 当网桥判断出目的 MAC 地址不在 MAC 表中时,会将数据帧发往桥的另一端。但是网桥并不知道另一端是否存在这个地址(事实上绝大部分时间都不在)。
- 在一些特殊的场景下,如广播 / 多播需求,网桥会将数据帧扩散到整个网络上,造成广播风暴。
交换机 Switch
- 交换机是一种性能增强版的网桥。
- 交换机通常具有较多的端口,每两个端口都可以作为一组网桥来使用。交换机可以看做是一堆网桥的合集。
- 同网桥一样交换机也维护了端口到 MAC 地址的映射表
两者在逻辑模型上并没有更多的区别。
网桥、交换机与生成树协议
拓展一下上面的例子,把两个端口的网桥换成多端口网桥(交换机),会出现这样一种网络拓扑:
flowchart LR c1(A fas:fa-desktop) c2(B fas:fa-desktop) b1(fas:fa-network-wired 网桥1) b2(fas:fa-network-wired 网桥2) b3(fas:fa-network-wired 网桥3) c1 --> | AtoB| b1 b1 --- b2 b1 --- b3 b2 --- b3 b3 --- c2 %%
图中是一个三个网桥形成的环状结构,其中主机 A 发出一个数据帧 AtoB
,根据上文的模型,B 的 MAC 地址不在网桥 1 左侧端口的 MAC 表中,网桥 1 会将 AtoB
转发至另外的两个端口:
flowchart LR c1(A fas:fa-desktop) c2(B fas:fa-desktop) b1(fas:fa-network-wired 网桥1) b2(fas:fa-network-wired 网桥2) b3(fas:fa-network-wired 网桥3) c1 --- b1 b1 --> | AtoB| b2 b1 --> | AtoB| b3 b2 --- b3 b3 --- c2 %%
再下一步,网桥 2 将左侧端口收到的数据帧向右侧端口转发,同时网桥 3 将收到的数据帧向其余两个端口转发:
flowchart LR c1(A fas:fa-desktop) c2(B fas:fa-desktop) b1(fas:fa-network-wired 网桥1) b2(fas:fa-network-wired 网桥2) b3(fas:fa-network-wired 网桥3) c1 --- b1 b1 --- b2 b1 --- b3 b2 -.-> | AtoB| b3 b3 --> | AtoB| c2 b3 -.-> | AtoB| b2 %%
可以看出网桥 2 和网桥 3 会互相转发 AtoB 这个数据帧。如果不加干预的话,并且这个数据帧会一直在这个三个网桥形成的环中传递。
为了解决这个问题,网桥都具备一个 “破环功能”,该功能实现的原理是:最小生成树协议。这个协议详情本文不做说明,后面的 Blog 再写这个。