0

    从你输入一个网址,到网页显示,其间发生了什么?

    2023.05.22 | admin | 145次围观

    假设客户端有多个网卡,就会有多个 IP 地址,那 IP 头部的源地址应该选择哪个 IP 呢?

    当存在多个网卡时,在填写源地址 IP 时,就需要判断到底应该填写哪个地址。这个判断相当于在多块网卡中判断应该使用哪个一块网卡来发送包。

    这个时候就需要根据路由表规则,来判断哪一个网卡作为源地址 IP。

    在 Linux 操作系统,我们可以使用 route -n 命令查看当前系统的路由表。

    路由表

    举个例子,根据上面的路由表,我们假设 Web 服务器的目标地址是 192.168.10.200。

    路由规则判断

    首先先和第一条条目的子网掩码(Genmask)进行与运算,得到结果为 192.168.10.0,但是第一个条目的 Destination 是 192.168.3.0,两者不一致所以匹配失败。

    再与第二条目的子网掩码进行与运算,得到的结果为 192.168.10.0,与第二条目的 Destination 192.168.10.0匹配成功,所以将使用 eth1 网卡的 IP 地址作为 IP 包头的源地址。

    那么假设 Web 服务器的目标地址是 10.100.20.100,那么依然依照上面的路由表规则判断,判断后的结果是和第三条目匹配。

    第三条目比较特殊,它目标地址和子网掩码都是0.0.0.0,这表示默认网关,如果其他所有条目都无法匹配,就会自动匹配这一行。并且后续就把包发给路由器,Gateway 即是路由器的 IP 地址。

    IP 报文生成

    至此,网络包的报文如下图。

    IP 层报文

    此时,加上了 IP 头部的数据包表示 :“有 IP 大佬给我指路了,感谢 IP 层给我加上了 IP 包头,让我有了远程定位的能力!不会害怕在浩瀚的互联网迷茫了!可是目的地好远啊,我下一站应该去哪呢?”

    06 两点传输 —— MAC

    生成了 IP 头部之后,接下来网络包还需要在 IP 头部的前面加上 MAC 头部。

    MAC 包头格式

    MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息。

    MAC 包头格式

    在 MAC 包头里需要发送方 MAC 地址和接收方目标 MAC 地址,用于两点之间的传输。

    一般在 TCP/IP 通信里,MAC 包头的协议类型只使用:

    MAC 发送方和接收方如何确认?

    发送方的 MAC 地址获取就比较简单了,MAC 地址是在网卡生产时写入到 ROM 里的,只要将这个值读取出来写入到 MAC 头部就可以了。

    接收方的 MAC 地址就有点复杂了,只要告诉以太网对方的 MAC 的地址,以太网就会帮我们把包发送过去,那么很显然这里应该填写对方的 MAC 地址。

    所以先得搞清楚应该把包发给谁,这个只要查一下路由表就知道了。在路由表中找到相匹配的条目,然后把包发给 Gateway 列中的 IP 地址就可以了。

    既然知道要发给谁,按如何获取对方的 MAC 地址呢?

    不知道对方 MAC 地址?不知道就喊呗。

    此时就需要 ARP 协议帮我们找到路由器的 MAC 地址。

    ARP 广播

    ARP 协议会在以太网中以广播的形式,对以太网所有的设备喊出:“这个 IP 地址是谁的?请把你的 MAC 地址告诉我”。

    然后就会有人回答:“这个 IP 地址是我的路由器输入网址进不去,我的 MAC 地址是 XXXX”。

    如果对方和自己处于同一个子网中,那么通过上面的操作就可以得到对方的 MAC 地址。然后,我们将这个 MAC 地址写入 MAC 头部,MAC 头部就完成了。

    好像每次都要广播获取,这不是很麻烦吗?

    放心,在后续操作系统会把本次查询结果放到一块叫做 ARP 缓存的内存空间留着以后用,不过缓存的时间就几分钟。

    也就是说,在发包时:

    查看 ARP 缓存内容

    在 Linux 系统中,我们可以使用 arp -a 命令来查看 ARP 缓存的内容。

    ARP 缓存内容

    MAC 报文生成

    至此,网络包的报文如下图。

    MAC 层报文

    此时,加上了 MAC 头部的数据包万分感谢路由器输入网址进不去,说道 :“感谢 MAC 大佬,我知道我下一步要去了哪了!我现在有很多头部兄弟,相信我可以到达最终的目的地!”。带着众多头部兄弟的数据包,终于准备要出门了。

    07 出口 —— 网卡

    IP 生成的网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电信号,才能在网线上传输,也就是说,这才是真正的数据发送过程。

    负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序。

    网卡驱动从 IP 模块获取到包之后,会将其复制到网卡内的缓存区中,接着会其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。

    物理层数据包

    最后网卡会将包转为电信号,通过网线发送出去。

    唉,真是不容易,发一个包,真是历经历经千辛万苦。致此,一个带有许多头部的数据终于踏上寻找目的地的征途了!

    08 送别者 —— 交换

    下面来看一下包是如何通过交换机的。交换机的设计是将网络包原样转发到目的地。交换机工作在 MAC 层,也称为二层网络设备。

    交换机的包接收操作

    首先,电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。

    然后通过包末尾的 FCS 校验错误,如果没问题则放到缓冲区。这部分操作基本和计算机的网卡相同,但交换机的工作方式和网卡不同。

    计算机的网卡本身具有 MAC 地址,并通过核对收到的包的接收方 MAC 地址判断是不是发给自己的,如果不是发给自己的则丢弃;相对地,交换机的端口不核对接收方 MAC 地址,而是直接接收所有的包并存放到缓冲区中。因此,和网卡不同,交换机的端口不具有 MAC 地址。

    将包存入缓冲区后,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了。

    交换机的 MAC 地址表主要包含两个信息:

    交换机的 MAC 地址表

    举个例子,如果收到的包的接收方 MAC 地址为00-02-B3-1C-9C-F9,则与图中表中的第 3 行匹配,根据端口列的信息,可知这个地址位于 3 号端口上,然后就可以通过交换电路将包发送到相应的端口了。

    所以,交换机根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口。

    当 MAC 地址表找不到指定的 MAC 地址会怎么样?

    地址表中找不到指定的 MAC 地址。这可能是因为具有该地址的设备还没有向交换机发送过包,或者这个设备一段时间没有工作导致地址被从地址表中删除了。

    这种情况下,交换机无法判断应该把包转发到哪个端口,只能将包转发到除了源端口之外的所有端口上,无论该设备连接在哪个端口上都能收到这个包。

    这样做不会产生什么问题,因为以太网的设计本来就是将包发送到整个网络的,然后只有相应的接收者才接收包,而其他设备则会忽略这个包。

    有人会说:“这样做会发送多余的包,会不会造成网络拥塞呢?”

    其实完全不用过于担心,因为发送了包之后目标设备会作出响应,只要返回了响应包,交换机就可以将它的地址写入 MAC 地址表,下次也就不需要把包发到所有端口了。

    局域网中每秒可以传输上千个包,多出一两个包并无大碍。

    此外,如果接收方 MAC 地址是一个广播地址,那么交换机会将包发送到除源端口之外的所有端口。

    以下两个属于广播地址:

    数据包通过交换机转发抵达了路由器,准备要离开土生土长的子网了。此时,数据包和交换机离别时说道:“感谢交换机兄弟,帮我转发到出境的大门,我要出远门啦!”

    09 出境大门 —— 路由器

    路由器与交换机的区别

    网络包经过交换机之后,现在到达了路由器,并在此被转发到下一个路由器或目标设备。

    这一步转发的工作原理和交换机类似,也是通过查表判断包转发的目标。

    不过在具体的操作过程上,路由器和交换机是有区别的。

    路由器基本原理

    路由器的端口具有 MAC 地址,因此它就能够成为以太网的发送方和接收方;同时还具有 IP 地址,从这个意义上来说,它和计算机的网卡是一样的。

    当转发包时,首先路由器端口会接收发给自己的以太网包,然后路由表查询转发目标,再由相应的端口作为发送方将以太网包发送出去。

    路由器的包接收操作

    首先,电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的 FCS 进行错误校验。

    如果没问题则检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包。

    总的来说,路由器的端口都具有 MAC 地址,只接收与自身地址匹配的包,遇到不匹配的包则直接丢弃。

    查询路由表确定输出端口

    完成包接收操作之后,路由器就会去掉包开头的 MAC 头部。

    MAC 头部的作用就是将包送达路由器,其中的接收方 MAC 地址就是路由器端口的 MAC 地址。因此,当包到达路由器之后,MAC 头部的任务就完成了,于是 MAC 头部就会被丢弃。

    接下来,路由器会根据 MAC 头部后方的 IP 头部中的内容进行包的转发操作。

    转发操作分为几个阶段,首先是查询路由表判断转发目标。

    路由器转发

    具体的工作流程根据上图,举个例子。

    假设地址为 10.10.1.101 的计算机要向地址为 192.168.1.100的服务器发送一个包,这个包先到达图中的路由器。

    判断转发目标的第一步,就是根据包的接收方 IP 地址查询路由表中的目标地址栏,以找到相匹配的记录。

    路由匹配和前面讲的一样,每个条目的子网掩码和 192.168.1.100 IP 做& 与运算后,得到的结果与对应条目的目标地址进行匹配,如果匹配就会作为候选转发目标,如果不匹配就继续与下个条目进行路由匹配。

    如第二条目的子网掩码 255.255.255.0与 192.168.1.100 IP 做& 与运算后,得到结果是 192.168.1.0,这与第二条目的目标地址 192.168.1.0匹配,该第二条目记录就会被作为转发目标。

    实在找不到匹配路由时,就会选择默认路由,路由表中子网掩码为0.0.0.0的记录表示「默认路由」。

    路由器的发送操作

    接下来就会进入包的发送操作。

    首先,我们需要根据路由表的网关列判断对方的地址。

    知道对方的 IP 地址之后,接下来需要通过 ARP 协议根据 IP 地址查询 MAC 地址,并将查询的结果作为接收方 MAC 地址。

    路由器也有 ARP 缓存,因此首先会在 ARP 缓存中查询,如果找不到则发送 ARP 查询请求。

    接下来是发送方 MAC 地址字段,这里填写输出端口的 MAC 地址。还有一个以太类型字段,填写0080(十六进制)表示 IP 协议。

    网络包完成后,接下来会将其转换成电信号并通过端口发送出去。这一步的工作过程和计算机也是相同的。

    发送出去的网络包会通过交换机到达下一个路由器。由于接收方 MAC 地址就是下一个路由器的地址,所以交换机会根据这一地址将包传输到下一个路由器。

    接下来,下一个路由器会将包转发给再下一个路由器,经过层层转发之后,网络包就到达了最终的目的地。

    不知你发现了没有,在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输。

    数据包通过多个路由器道友的帮助,在网络世界途径了很多路程,最终抵达了目的地的城门!城门值守的路由器,发现了这个小兄弟数据包原来是找城内的人,于是它就将数据包送进了城内,再经由城内的交换机帮助下,最终转发到了目的地了。数据包感慨万千的说道:“多谢这一路上,各路大侠的相助!”

    10 互相扒皮 —— 服务器 与 客户端

    数据包抵达了服务器,服务器肯定高兴呀,正所谓有朋自远方来,不亦乐乎?

    服务器高兴的不得了,于是开始扒数据包的皮!就好像你收到快递,能不兴奋吗?

    扒皮模型

    数据包抵达服务器后,服务器会先扒开数据包的 MAC 头部,查看是否和服务器自己的 MAC 地址符合,符合就将包收起来。

    接着继续扒开数据包的 IP 头,发现 IP 地址符合,根据 IP 头中协议项,知道自己上层是 TCP 协议。

    于是,扒开 TCP 的头,里面有序列号,需要看一看这个序列包是不是我想要的,如果是就放入缓存中然后返回一个 ACK,如果不是就丢弃。TCP头部里面还有端口号, HTTP 的服务器正在监听这个端口号。

    于是,服务器自然就知道是 HTTP 进程想要这个包,于是就将包发给 HTTP 进程。

    版权声明

    本文仅代表作者观点。
    本文系作者授权发表,未经许可,不得转载。

    发表评论