一个数据包的奇幻旅程(上)【译文】

2021-09-02
翻译

前言

最近读到一篇很好的关于互联基础知识文章,之前关注HTTP和TCP这类上层的协议比较多,读完这篇文章之后之后受益匪浅,对互联网更底层的原理和设计理念有了进一步的了解,除了文章内容写的简介易懂之外,文章的插图也好,尤其用了很多有趣的动图演示网络传输的过程,下面是读完这篇文章之后的一张思维导图。
image1.png

原文属于系列文章,我将他们翻译成中文,整理在一起形成一整篇长文,原文地址:https://www.practicalnetworking.net/series/packet-traveling/packet-traveling/,感兴趣的读者可以阅读原文,以下是翻译的文字:

如果你正在读这篇博客,那么你可能已经很熟悉互联网,互联网毫无疑问是一个了不起的发明。它使得来自世界各地的计算机可以互相通信。
当数据离开你的计算机,它会被分成小的数据块或数据包。这些数据包本质上就行像携带数据的信封,能够到达互联网的各个角落。
这篇文章将会解释数据包从一个终端到另一个终端的所有有关的细节,我们会了解一个数据包在网络上传输时经过的每一个设备和步骤。
但是首先,我们需要先了解一些网络通信方面相对比较独立的背景知识,然后我们再深入了解每个网络设备所扮演的角色。最后我们会从整体的角度看一下连接两台计算机之间的所有网络设备的功能。

image2.gif

这篇文章主要包含以下几个主题:

  • OSI网络模型
  • 关键设备
  • 两台直连主机之间的通信
  • 通过交换机连接的两台主机之间的通信
  • 通过路由器连接的两台主机之间的通信
  • 通过交换机和路由器连接的两台主机之间的通信

通过阅读这篇系列文章,你将会理解两台主机通信时所发生的所有事情。

OSI网络模型

开放式系统互联通信参考模型(Open System Interconnect)简称OSI,规定了互联网运行所需的各个功能。他是一个包含了网络七层模型一整套规范,这些相互独立的而又联系的层组合在一起,共同实现了网络通信。

这很像是一辆汽车,把各个独立的功能模块组合在一起实现向前移动的目的:一块电池为电气设备供电,一个交流发电机为电池充电,引擎带动传动轴,传动轴再带动车轮,以此类推。每个独立的设备可以单独更换,只要各个设备工作正常,车辆就可以向前移动。
OSI模型也是一样的道理,它被划分成了七层,每一层都负责特定的功能,他们组合在一起实现了计算机之间的数据通信。
image3.png
接下来我们来介绍各个层的职责。

物理层(L1)

OSI模型的物理层负责传输比0,1比特流,他们是计算机中最基本的构成代码。
这一层代表的是物理介质,主要负责在两个节点之间传输数据,典型的代表有网络电缆和串型线,但是不要太过纠结“物理”这一名词,因为物理层的概念出现在19世纪70年代,远早于无线网络通信的概念,因此,尽管WI-FI没有物理上可感知的设备,但他仍然属于物理层。简单的说,物理层指所有能够传输0和1的设备。
但是实际的数据格式根据每种介质的不同,又是多种多样的。以太网中,比特流通过电流脉冲的形式传输,在WI-FI中比特流以以电磁波的形式传输,而在光纤中,比特流又会以光脉冲的形式传输。
image4.png
除了物理电缆之外,中继器和集线器也工作在这一层。
中继器比较简单,他是对一个介质到另一个介质的信号进行中继,这允许一系列的物理电缆连接在一起,来突破单一设备传输范围限制,增大传输距离。最常见的就是大型的WI-FI部署,一个单独的WI-FI网络被中继扩大,已覆盖更大的范围。集线器是一个简易的多端口中继器,假如有四个设备连接到一个集线器上,其中一个设备发送的数据可以被中继到另外三个设备上。

数据链路层(L2)

OSI模型的数据链路层主要面向物理层,事实上,数据链路层负责从电线上获取和传输0,1比特。
网卡(又称网络适配器,Network Interface Card, NIC)就工作在这一层,既可以接收来自网线的信号,也向网线传输信号。无线(WI-FI)网卡也是同样的工作原理,它接收和传输电磁波,并将他们翻译成0和1。
这一层将0和1组成的数据块称之为桢。这一层存在一个地址系统称为媒体访问控制(Media Access Control)地址,也就是我们熟知的的MAC地址,MAC地址是唯一的,可以确定一块网卡。每张网卡都会被网卡硬件制造商写入一个MAC地址,写入的方式被称之为烧录地址(Burned In Address, BIA)。
image5.png
除了网卡之外,交换机也工作在这一层,他的主要职责是负责网络内的主机通信(后面会有详细介绍)。
数据链路层的首要工作就是将数据包从一张网卡传输到另一张网卡,或者换一种说法,数据链路层在节点与节点之间传输数据。

网络层(L3)

OSI模型的网络层主要负责端到端的数据传输。这一层会利用另一个地址系统来从逻辑上识别任意一个接入互联网的节点,就是我们熟知的IP地址(Internet Protocol address)。之所以称为逻辑地址是因为IP地址并不能永久标识一台计算机,不像MAC地址是一个物理地址,IP地址不会设备制造商烧录进硬件中去。
路由器就是工作在网络层的设备,它负责网络之间的通信,路由器是不同网络之间的边界,任何没有直接接入网络的设备,都必须依靠路由器才能实现网络通信。

数据链路层 VS. 网络层

想要理解数据在两台计算机之间是如何流动的,就必须要搞清楚数据链路层和和网络是如何交互的,以及他们之间的区别。比如,我们已有了唯一的MAC地址,为什么我们还需要IP地址?或者反过来说,我们已经有了IP地址,为什么还需要MAC地址?
答案是这两个地址功能不同:

  • 数据链路层的MAC地址负责节点之间的数据传递
  • 网络层的IP地址负责终端之间的数据传递
    计算机发送数据时,数据会被封装一个IP头,包括通信的两个终端的源IP地址和目标IP地址,IP头和数据一起会被封装一个MAC地址头,它包含网络数据在网络路径上传递时,各个节点的MAC地址。

如下图所示
image6.gif
注意两个路由器之间,MAC地址会被剥离并重新生成下一个节点的MAC地址,而由初始发送方计算机生成的IP数据包头只会被最终的接收方计算机剥离。因此,我们说IP数据包头是“端到端”的,MAC地址是“节点到节点”的。

传输层(L4)

OSI网络模型的传输层负责区分不同的网络数据流。任意时刻,用户可能同时开着浏览器,听着音乐或用聊天软件聊天。每个软件都在从互联网发送和接收数据,这些所有的数据都以二进制的形式在算机网卡上传输,所以必须有一套机制来区分出哪些二进制数据属于浏览器,哪些数据属于音乐播放器,哪些数据属于聊天软件等等。这就是传输层要做的事情。
image7.png

传输层完成这一功能的方式就是我们熟知的端口号。具体来说,传输层有两种协议能够区分网络数据流——TCP和UDP。
TCP和UDP都有65536个端口号可用,一个应用的数据可以通过原端口和目标端口号唯一确定(实际上还有源IP和目标IP)。TCP和UDP在数据的传输方式上采用不用的策略,理解他们的区别和内部工作原理也至关重要,但是这些知识超出了这篇文章的主题,所以我们暂时不去讨论它。
总结一下,如果我们说数据链路层是负责节点之间的传输,网络层负责端到端的数据传输,那么我们可以说传输层是负责应用程序到应用程序的数据传输。

应用层(L5, L6, L7)

OSI七层网络模型的会话层,表示层,和应用层负责的是数据从网络上传输并呈现给用户前的最后一个步骤。从纯网络工程的角度来看,这三层之间的区别并不重要,在另外一个著名的TCP/IP网络模型中,这三层就被划分进了同一层——应用层。而如果你是从事软件工程的,他们的区别对你来说会比较重要。这也不是这篇文章要讨论的主题,所以我们不会深入讨论。

数据封装和解析

最后一个我们需要讨论的OSI网络模型的知识点是数据封装和拆封。主要涉及数据如何在发送端从最上层到达最下层,又如何在接收端从最下层到达最上层。由于数据是一层一层处理的,在数据被转换成0和1传输到网线之前,每一层为了完成各自的功能,都需要添加一些必要的信息。例如:

  • 传输层会添加TCP数据包头,主要包括源端口和目标端口
  • 网络层会添加IP数据包头,主要包括源IP和目标IP地址
  • 数据链路层会添加源MAC地址和目标MAC地址
    在接收端,每一层会从数据包上剥离这些头信息,并向上传递给模型栈的上一层,直到应用层。
    image8.gif

注意这只是一个例子,每一层具体添加的头信息取决于改模型层的具体协议,比如在传输层也可以添加UDP头信息,在网络层可以添加IPv6头信息。
不论哪种方式,重要的是我们要理解这个过程,即数据在传输给网线时,数据在模型栈中从上向下传递,每一层为了完成特定的工作,都会添加一些头信息。在接收端,数据向上到达应用层之前,这些头信息会被一层一层的解析。

这篇文章以OSI网络模型不同层的方式对网络的各个功能进行了分类,理解数据包在网络上传递是如何传递的,OSI模型并不是必须要遵守的,它只是一个理论上的概念模型——即不是所有的协议都完全遵守每一层的规定。

关键设备

互联网的神奇之处在于它能够使所形形色色的设备组合在一起工作,它创建出的万维网允许数以亿计的设备能够相互通信。接下来我们会讨论网络中一些关键的设备,以及他们在实现网络通信时所扮演的角色。
这个列表并不是完整的,但是却涵盖了主要“演员”。在理解数据包的网络传输时,他们的功能是你必须要了解的。

主机

主机是一个比较宽泛的概念,包含各种各样的网络设备,任何设备,既可以是网络数据传输的起点,也可以是网络数据传输的终点,这些都可以被称为主机。传统的例子是计算机或笔记本电脑,但是在现代,主机包含的设备更多:手机,智能电视,智能手表,某些汽车,甚至一些冰箱。主机上会运行一些能够和终端用户交互的应用软件,这些软件需要发送网络数据,因此,我们可以说主机工作在OSI模型的所有层。在典型的网络中,通信的两台主机通常被称为客户端和服务端。
客户端指的是为了获取信息、数据或服务,而发送请求的一方,服务端指的是拥有这些信息、数据或服务,收到请求的一方。客户端和服务端是一个相对的概念。比如,你正在用笔记本电脑浏览网页,那么你的笔记本扮演的是客户端的角色,Web服务器扮演的是服务端的角色。但是当这个Web服务器在下载软件更新,和更新服务器通信时,他扮演的又是客服端的角色。
image9.png

网络

网络指的是相互连接的两个或两个以上的设备。通常他们根据相同的目的或物理位置被组合在一起。网络可以有很多种形式,比如:

  • 一间教室的一组计算机,他们处于同一个物理空间中,属于同一个网络。
  • 一个典型的家庭网络,包括多个笔记本电脑,智能手机或打印机,他们被绑定同一个物理地址,因此他们属于同一个网络。
  • 一个咖啡厅有一个允许客户连接的WI-FI网络
  • 一个公司根据各个部门的职能有多个网络,比如财务部的所有会计人员一个网络,所有的工程师在另一个网络

依赖于每个网络的用途,接入这些网络的设备可以和同一个网络内的其他设备通信,也可以和不同网络的其他设备通信。接下来这篇文章讨论的所有关键设备都是相互连接的,实际上我们的互联网无非就是由很多个小的网络组合在一起的。

交换机

交换机是负责网络内部通信的网络设备。交换机工作在OSI网螺模型的数据链路层,这意味着他会解析每个数据报的数据链路层包头,这些数据包头包含源节点的MAC地址和相邻目标节点的MAC地址。
image10.png
交换机会维护一份MAC地址表,这个表记录了设备的MAC地址和对应交换机端口的映射。一个交换机通常有很多端口,有24个的,48个的,96个的,甚至更多。
MAC地址表的映射记录来自每个数据帧的源MAC地址字段,为了转发数据,交换机会查看MAC地址表里目标MAC地址的端口,然后将数据发往这个端口。假如交换接收到一个数据帧,这个数据帧包含一个未知的MAC地址,他会重复的将这个数据帧发送到除了接收端口以外的所有其他端口,这个过程称之为过滤和泛洪,后面会详细介绍这个过程。

路由器

路由器主要负责不同网络之间的通信,一个路由器的每个接口会创建一个网络边界,路由器工作在OSI模型的网络层,这意味着它会解析每个数据报的网络层数据包头,包括源终端的IP地址和目标终端的IP地址。
image11.png

上图中,左边路由器R1和右边的路由器R2创建了三不同的网络,他们的网址分别是11.11.11.x,22.22.22.x和33.33.33.x,R1右边接口和R2的左边接口是同一个网络。
11.11.11.x网络内的客户端和33.33.33.x内的服务器通信的唯一方式是先将数据转发给R1,然后在转发给R2,最后再将数据转发给服务器。
路由器通过维护的一份路由表来实现路由的功能,路由表包含所有可抵达网络的路径,这些路径被称为路由,路由主要记录网络的IP地址或者通信路径上其他路由器的IP地址。路由器维护路由表的主要方式是路由学习,路由学习有若干方式,接下来我们会讲述这些不同的方式。
但是我们首先要记住的是,从路由器的角度来讲,路由表是已存在网络的IP地址映射,也就是说,如果一个路由器,接收到一个数据包含一个未知网络的IP地址,那么路由器会认为这个网络不存在,路由器会将这样的数据丢弃。

地址解析协议

地址解析协议,即ARP(Address Resolution Protocol),之前我们讨论过MAC地址属于数据链路层的地址,IP地址是网络层的地址,连接这两个地址的桥梁就是地址解析协议,即ARP。通常情况下,通信的双方总是已经知道对方的IP地址,获取对方IP地址的方式有很多种,比如由用户手动提供,或者用过DNS协议获取。然而,通信的双方不知道对方的MAC地址,这就是ARP所做的事情,换句话说,ARP协议是通过已知的IP地址,获取未知的MAC地址,两者之间的映射,会被添加并存储在ARP表中。下图演示了数据链路层和网络层之间的桥梁ARP以及ARP在这个过程中扮演的角色。
image12.png

上图中有三个网络,紫色网络,灰色网络和红色网络,我们将会用这个网络拓扑图来演示两种类型的APR:第一种是同一网络内紫色客户端和紫色的服务器的通信,第二种是紫色网络内的客户端到红色网络中的红色服务端。
当客户端需要合紫色的服务器通信时,客户端知道紫色服务器的IP地址,因此他能确定紫色服务器在本地网络内,所以客户端会向服务端发送ARP请求获取服务端的MAC地址。然后将获取到的MAC地址填充到数据链路层的数据包头中:
image13.png

当客户端需要与红色的服务器通信时,客户端知道服务器处于外网中,此时他会把数据包发给最近的路由器,就是我们说的默认网关。客户端通常会配置默认网关,例如上图中我们配置客户端的默认网关为R1。所以当客户端和外网的主机通信时,客户端会发送ARP请求获取默认网关的MAC地址。然后将获取到的MAC地址填充到数据链路层的数据包头中:
image14.png

总结一下ARP的功能:

  • 客户端和同一网络内主机通信时,ARP请求用于获取目标主机的MAC地址
  • 客户端和不同网络的主机通信时,ARP请求获取网络内默认网关的MAC地址

记住,ARP数据包的发送是由数据链路层完成的,因为这一层主要负责节点间的数据传输,而网络层关注的是端到端的数据传递,它不直接将数据传输到网线发送给对方主机的网卡。ARP的角色是基于网络层的数据头,帮助客户端拼装数据链路层的数据包头。以便将要发送的数据包传递给下一个节点。
还有需要注意的是,任何能够基于IP地址(网络层)进行数据包转发的设备,也必须能够将数据包发给下一个节点(数据链路层),任何利用IP地址的发送数据包的设备,也能够利用ARP和MAC地址,也就是说,所有的网络层设备也需要维护一份ARP表。

总结

上面简单回顾了一些基础的概念和互联网中常见设备的用途,以上的每个主题都有一整本书来讲述,后面会将这些概念联系在一起,做更深入的讨论,但是在往下读之前,请确保你已经理解上面所讲的。
上文讨论了OSI模型每一层的主要职责:

  • 物理层(L1)是用于传输二进制代码的物理媒介,如网线。
  • 数据链路层利用MAC地址负责数据在节点之间的传递。
  • 网络层利用IP地址负责数据在通信终端之间的传递。
  • 传输层利用端口号,将不同的数据分发给不同的应用。
    我们还讨论了网络传输过程中,一些关键设备所扮演的角色:
  • 交换机工作在数据链路层,负责网络内主机的通信。
  • 路由器工作在网络层,负责不同网络之间的数据通信。
  • ARP利用已知的IP地址获取MAC地址

我们还讨论了三个不同的表存储了三种不同的映射关系:

  • 交换机的MAC地址表存储了不同设备MAC地址和交换机端口之间的映射关系
  • 路由器的路由表保存了已知网络的IP地址
  • 所有的网络层设备都有ARP表,用以存储IP地址和MAC地址之间的映射