计算机网络学习笔记(1)—— 物理层与链路层

Posted by 皮皮潘 on 02-15,2022

网络包分层

网络包的装包与分包如下图所示:
1506_1.png

网络包的核心准则就是:只要是在网络上跑的包,都是完整的。可以有下层没上层,绝对不可能有上层没下层。

物理层

物理层其实就是最底层的传输介质的那一层,如:网线、无线网等,在该层仅仅负责数据包的传输(将包从一个地方传到另外一个地方)至于目标地方是不是真正的接受者,信号冲突了怎么办,数据包怎么处理等问题一律由高层的协议去解决。

网线

如果想要使得两台电脑连接起来,最简单的方式是买一根网线让两台电脑互联,当然普通的网线这样是通不了的,要对于水晶头做一个交叉线(13-26交叉线):将一端的水晶头的1、3脚和2、6脚交换一下位置才可以让两台电脑互联。因为网线一共有8根 第1、2根起着收信号的作用,第3、6根起着发信号的作用。这边的1、2占着另外一边的3、6根的位置,由于物理层网线仅仅是数据的传递,那么另外一边发信号到了这边之后就会直接进入接收口了, 同理这边3、6占着另外一边1、2根的位置。那么这边发信号,另外一边就能收到了。除了网线要交叉之外,再手动配置一下两个电脑的IP地址、子网掩码和默认网关在同一个网段下,两个电脑就能通信了

Hub集线器

如果是要多台机子互联的话,在物理层可以使用集线器Hub将他们连接在一起,这种设备有多个口,可以将多台电脑连接起来。但是和交换机不同的点在于,集线器没有大脑,它完全在物理层工作:它会将自己收到的每一个字节放大,然后都复制到其他端口上去。这也是多台机子第一层物理层联通的方案。但是由于Hub只是一个信号放大器,没有缓存机制,并工作在半双工模式下(后文会解释),所以任何时刻只能由一台电脑发数据给Hub,如果有多台电脑同时发数据给HUB,会产生冲突,因此需要上层协议也即链路层来解决冲突的问题

全双工与半双工

全双工就是有两条单工线路分别负责承载一个方向的信号大家互不干扰,像网线就是全双工的,而半双工就是有一条双向的线路,但是同一时间只能承载一个方向的信号

既然全双工与半双工指的是传输模式,而网线又是全双工的,那么为什么说Hub工作在半双工模式下呢,因为Hub是一个简单的信号放大器,无论怎么样它都会将数据包广播给所有人,这就导致了如果有两个设备同时给Hub传输信号的话,Hub会把两段信号同时广播给所有人,这导致了信号的混杂,最后谁都分辨不清楚,所以哪怕是全双工网线也没有任何意义,这样的交流机制同时也可以可以称作半双工

链路层

正如前文所说,链路层并不单单只是简单的MAC地址而已,该层的核心在于解决媒体接入控制(MAC)的问题,MAC地址也是由此而来的,该问题主要包括三个子问题:1. 包接收者问题 2. 信号冲突问题 3. 包数据错误问题

问题解决方案

包接收者问题

解决该问题就牵扯到了链路层网络包格式,对于以太网,第二层的最开始就是目标MAC地址和源MAC地址,接下来是类型,大部分的类型是 IP 数据包,也会存在 ARP 数据包,然后 IP 里面包含 TCP、UDP,以及 HTTP 等,这都是里层封装的事情。有了这个目标 MAC 地址,数据包在物理层上广播,目标 MAC 的网卡才能发现,这个包是给它的。MAC 的网卡把包收进来,然后打开 IP 包,发现 IP 地址也是自己的,再打开 TCP 包,发现端口是自己,也就是 80,而 nginx 就是监听 80。

信号冲突问题

这个问题的解决方案叫做多路访问,有很多算法可以解决这个问题,主要有如下三种方式:

方式一:分多个车道。每个车一个车道,你走你的,我走我的。这在计算机网络里叫作信道划分;

方式二:今天单号出行,明天双号出行,轮着来。这在计算机网络里叫作轮流协议;

方式三:不管三七二十一,有事儿先出门,发现特堵,就回去(冲突检测)。错过高峰再出(随机等待)。我们叫作随机接入协议。在以太网下用的就是这个方式。

包数据错误问题

在链路层网络包格式中的最后面会携带一个CRC,也就是循环冗余检测,它通过 XOR 异或的算法,来计算整个包的一个摘要,接收方可以通过再次计算该摘要并对比来判断,是否在发送的过程中出现了错误

MAC地址和IP地址

可能有人会问,既然MAC地址已经解决了包接收者的问题,那为什么还要IP地址呢?这是因为MAC地址虽然有一定定位功能,但是范围非常有限仅仅在局域网内有用,而IP地址的定位范围则远大于MAC,它可以应用在整个广域网中,从寻址的角度而言,MAC地址可以类比为一个人的身份证作为唯一标识,而IP地址可以类比为一个人的居住地地址,在现实生活中往往是通过居住地地址而不会直接通过身份证来找到一个人的,接下来也会通过另外一篇博文详细介绍一下IP层

ARP协议

其实这里还有一个问题,就是如果源机器知道目标机器的MAC地址,那么可以直接就放入到MAC包中,但是如果不知道呢,总不能每次都广播吧?这时候就需要一个通过目标IP地址来求对应的目标MAC地址的协议了,也即ARP协议

其实ARP协议很简单,就是“吼一声”(广播),发送一个ARP广播包,谁是这个IP谁来回到,具体询问和回答的报文如下图所示:
1508_1.png

为了避免每次都用 ARP 请求,机器本地也会进行 ARP 缓存。当然机器会不断地上线下线,IP 也可能会变,所以 ARP 的 MAC 地址缓存过一段时间就会过期。

交换机

使用之前提及的一层物理设备集线器Hub组网的话,在电脑数量少的情况下尚可,但是一旦电脑数量多了,由于Hub是不管三七二十一都广播转发的设备,这会导致转发大量不需要的包,同时Hub又是工作在半双工模式下的所有端口都在同一个冲突域中,数据包增多了也就导致了冲突概率增大的问题,那么如何解决这两个个问题呢?这就要请出交换机了

对于包无效转发问题,由于每个口都只连接一台电脑,而电脑又不怎么换IP和MAC地址,因此只要对于交换设备而言只要记住每台电脑的MAC地址,如果目标MAC地址不是这台电脑的,那么这个口就不用转发,那么也就可以大大减少不必要的转发浪费,而交换机在工作中就能把 MAC 头拿下来检查目标 MAC 地址,然后根据策略转发同时又可以自动学习记录每个口对应的电脑的MAC地址(转发表)从而实现包的有效转发

对于包冲突问题,因为交换机,会有选择地转发数据包而不是全都广播,因此它工作在全双工模式下,每个端口都是一个单独的冲突域,不同端口之间的数据包不会互相冲突,交换机对于入口的数据包会直接进行交换,当然如果该出端口中正在传输数据,那么也不能直接传输,不然就导致了信号混杂,此时交换机会则用缓存队列缓存对应的包,等出端口一空闲立马就发送,从而降低了直接丢弃包带来的影响

拓扑结构

随着局域网的范围进一步增大,一个交换机可能就不够用了,此时就会需要多个交换机,交换机之间连接起来,就形成了一个复杂的拓扑结构,如下图所示,就是一个稍微复杂的拓扑结构,两台交换机连接着三个局域网,不同局域网网段相同因此也能互相访问,另外在每个局域网中可能也存在着Hub或者交换机,因此LAN2可以和两台交换机相连:
1512_1.png
在这种复杂拓扑情况下,MAC地址的查询(ARP)也会变得复杂起来,比如机器1想要去访问机器4,假设机器1已经知道机器4的IP了,此时它需要知道机器4的MAC地址,于是机器 1 发起广播,机器 2 收到这个广播,但是这不是找它的,所以没它什么事。交换机 A 一开始是不知道任何拓扑信息的,在它收到这个广播后,采取的策略是,除了广播包来的方向外,它还要转发给其他所有的网口。于是机器 3 也收到广播信息了,但是这和它也没什么关系。当然,交换机 B 也是能够收到广播信息的,但是这时候它也是不知道任何拓扑信息的,因而也是进行广播的策略,将包转发到局域网三。这个时候,机器 4 和机器 5 都收到了广播信息。机器 4 主动响应说,这是找我的,这是我的 MAC 地址。于是一个 ARP 请求就成功完成了。在上面的过程中,交换机 A 和交换机 B 都是能够学习到这样的信息:机器 1 是在左边这个网口的

当了解到这些拓扑信息之后,情况就好转起来。当机器 2 要访问机器 1 的时候,机器 2 并不知道机器 1 的 MAC 地址,所以机器 2 会发起一个 ARP 请求。这个广播消息会到达机器 1,也同时会到达交换机 A。这个时候交换机 A 已经知道机器 1 是不可能在右边的网口的,所以这个广播信息就不会广播到局域网二和局域网三

网络环路问题

虽然交换机在广播ARP请求的时候不会向广播包来的方向广播,但是当两个交换机将两个局域网同时连接起来的时候,也即出现环路的时候,就会导致ARP数据包一直在网络中转圈圈,如下图所示:
1514_1.png
在这种情况下,如果机器1想要知道机器2的MAC地址,那么就会广播一个ARP包到交换机A,交换机A将ARP包广播到局域网二了之后又会同步广播到交换机B,交换机B又将ARP包广播到局域网一导致同步到交换机A从而造成ARP包一直在网络中转圈圈,并导致广播包越来越多最后将网络堵死

除此之外,二层网络环路还会导致MAC地址漂移的问题,继续在上一个例子中,由于ARP包会同时发送到交换机A以及交换机B,因此交换机A和交换机B一开始都学习到了机器1在各自的左端口,都是此时交换机A又将ARP包广播给了局域网二导致又发送到了交换机B的右端口,此时交换机B就会以为机器1换了个地方,并重新学习该MAC地址,如此循环往复导致MAC地址漂移

为了解决该问题,需要通过STP(Spanning Tree Protocol)协议,将有环的图转变为生成树,从而变成无环的情况,由于STP协议比较复杂,因此将在之后单独的博文中给出

VLAN

随着机器的增多以及交换机的增多,广播问题和安全问题也逐渐显露了出来,如果每次广播都对于局域网中所有的机器发送,那么无疑带来极大的性能损耗以及安全上的问题,另外由于所有的局域网都在同一个网段中,可能会不小心访问到其他局域网的IP或者产生IP冲突的问题,为了解决上述问题,一种解决方案就是每个局域网对应一个单独的交换机,并配置单独的子网,但是这涉及到交换机硬件本身,如果网络拓扑结构需要发生改变,对应的硬件设备很难灵活地随之进行改变,另外一种解决方案就是VLAN也即虚拟局域网。

使用VLAN,一个交换机上会连接属于多个局域网的机器,且它们虽然连接在同一个局域网上,但是它们互不相通,也即广播包不会广播到除了自己局域网之外的其他局域网的机器中,那么交换机又是怎么区分哪个机器属于哪个局域网呢?

只需要在原来的二层的头上加一个 TAG,里面有一个12位的VLAN ID(支持2^12个虚拟局域网,更大的VLAN需要使用VXLAN支持)用来记录属于哪个局域网就可以了,如果交换机支持VLAN的话,我们可以设置交换机每个口所属的VLAN,当这个交换机把二层的头取下来的时候,如果头中没有VLAN ID(用户主机、服务器、Hub只能收发Untagged帧,VLAN ID其实是在数据包经过交换机端口的时候被附加上去的,因此用户主机、服务器无需知道自己所属的VLAN ID是多少,只要连上对应的交换机端口就可以了),它就会设置对应的VLAN ID,反之就直接识别对应的 VLAN ID,然后转发到相同VLAN ID对应的口中,不同 VLAN ID的包,是不会转发到对应的口中,从而实现了局域网之间的隔离,当拓扑结构发生改变时,只需要简单地改变交换机中端口所属的VLAN就可以了,另外交换机有一种口叫做Trunk口,它可以转发属于任何VLAN的口,因此交换机之间通过Trunk口进行相互连接

参考

  1. 《趣谈网络协议》
  2. 《计算机网络:自顶向下方法》