目录 ← 首页
CS168

首部

我们为什么需要首部?

在上一节中,我们了解到在第 3 层,数据以数据包的形式在互联网上传输。假设一个应用程序想要通过互联网发送一个文件,我们可以将文件的一部分比特放入一个数据包中,然后通过互联网发送。当交换机收到这一串 0 和 1 时,它根本不知道该如何处理这些比特。

img

打个比方,如果我给朋友写了一封信,直接交给邮局,邮局也不知道该怎么处理。相反,我们应该把信装进信封,在信封上写一些信息(比如朋友的地址),告诉邮局该如何处理这封信。

就像信封一样,当我们发送数据包时,需要附加额外的元数据,告诉网络基础设施该如何处理这个数据包。这些额外的元数据被称为首部。其余的比特(比如要发送的文件、信封里的信)被称为载荷

img

在这个类比中,邮局不应该阅读信的内容,它只需要看信封上的信息来决定如何寄送信件。同样,网络基础设施也只需要读取首部来决定如何传输数据。

收件人关心的是信的内容,而不是信封。同样,终端主机上的应用程序关心的是载荷,而不是首部。话虽如此,终端主机仍然需要了解首部,以便在发送数据包之前给数据包添加首部。

首部是标准化的

你也可以把首部看作是发送 / 接收数据的终端主机和承载数据的网络基础设施之间的接口(API)。当我们编写软件时,需要确定用户与我们的代码交互的接口(例如,用户可以调用哪些函数,这些函数的参数是什么)。同样,首部中的信息是用户使用网络功能和向网络传递参数的方式。

互联网上的每个设备(每个终端主机、每个交换机)都需要同意首部的格式。如果微软 Windows 修改其操作系统中的代码,发送具有不同首部结构的数据包,其他设备将无法理解这些发送的数据包。

这也意味着我们在设计首部时需要谨慎。一旦我们设计好首部并在互联网上部署,就很难改变设计(我们必须让所有人都同意修改)。这就是为什么标准制定机构可能会花费数年时间来设计和标准化首部。

首部应该包含什么?

首部应该包含哪些信息呢?

首部肯定要包含目的地址,它告诉我们数据包要发送到哪里。

首部还可以包含其他非必需但有用的信息。从技术上讲,源地址并不是传输数据包所必需的,但实际上,我们几乎总是在首部中包含源地址。这使得接收方能向发送方回复信息。

首部还可以包含校验和,以确保数据包在传输过程中没有损坏。

首部还可以包含其他元数据,比如数据包的长度。请注意,数据包的大小可能不同(例如,用户可能只需要发送几个字节)。

多个首部

让我们再回到邮政的类比。假设 A 公司的老板想给 B 公司的老板写一封信,这封信是如何发送的呢?

img

A 公司的老板把信折好交给秘书,秘书把信装进一个写有 B 公司老板全名的信封里。

img

秘书把这封信交给邮件室,邮递员把信放进一个标有 B 公司街道地址的箱子里,然后把这个包裹装上送货车。

img

此时,信本身被多层标识信息(信封、箱子)包裹着。快递公司会把信送到 B 公司(可能经过多辆卡车、飞机、邮递员等转运)。

img

当信到达 B 公司后,邮件室拆掉箱子,把信封交给秘书。

img

然后,秘书看到信封上老板的名字,拆掉信封,把信交给 B 公司的老板。

img

注意,当我们进入较低的抽象层时,我们会在数据周围包裹更多的首部。然后,当我们进入较高的抽象层时,我们会逐层剥离数据上的首部。

img

每一层只需要理解自己的首部,并且在某种意义上是与同一层的对等实体 “通信”。当 A 公司的秘书在信封上写名字时,那是给 B 公司的秘书看的(而不是给邮递员或老板看的)。

更正式地说,在互联网上,同一层的对等实体通过在该层建立协议来进行通信。该协议只对特定层的实体有意义。

img

请注意,有些层提供多种协议选择(例如,第 2 层的无线或有线协议)。在这种情况下,进行通信的双方需要使用相同的协议选择。有线发送方无法与无线接收方通信。

寻址与命名

前面我们说过,首部需要包含接收方的地址。那么这个地址到底是什么呢?正式来说,网络地址是某个值,它告诉我们主机在网络中的位置。

当我们更详细地研究不同的层时,会发现不同的层有不同的寻址方案。如果你想在 Soda Hall 里发送一封信,你可以把目的地址写成 “Soda Hall 413 室”,大楼里的人就知道该把信送到哪里。相比之下,如果你想把信寄到纽约,你就得写完整的街道地址,比如 “纽约州纽约市主街 123 号”。

同样,互联网中的不同层有不同的寻址方案,这些方案最适合该特定层。例如,有时主机通过其人类可读的名称来引用(例如www.google.com)。有时,同一台主机通过机器可读的 IP 地址来引用(例如 74.124.56.2),这个数字以某种方式编码了服务器的位置信息(如果服务器移动,这个地址可能会改变)。还有时,同一台主机可能通过其硬件 MAC 地址来引用,而 MAC 地址是永远不会改变的。

img

主机和路由器中的层

互联网不仅仅是发送方和接收方。除了两个终端主机外,还有路由器在多个跳段上转发数据包,使其朝着目的地传输。我们关于分层和首部的概念如何在所有这些设备上相互作用呢?

终端主机需要实现所有的层。你的电脑需要了解第 7 层才能运行网页浏览器,也需要了解第 1 层才能将比特通过线路发送出去。为了让应用层数据(老板的信)一路传递到物理层,你还需要中间的所有层。

那么路由器呢?路由器确实需要第 1 层来接收线路上的比特,需要第 2 层来沿线路发送数据包,需要第 3 层来在全球网络中转发数据包。然而,路由器实际上不需要考虑第 4 层和第 7 层。路由器不会运行网页浏览器来显示网页,也不需要考虑可靠性(回想一下尽力而为的服务模型)。

img

总结一下:较低的 3 层在所有地方都有实现,但顶部的 2 层只在终端主机上实现。

主机和路由器中的多个首部:类比

让我们再想想寄邮件的事情。A 公司把信装进信封,然后信封又被放进箱子里。这个箱子不会神奇地自己跑到 B 公司。事实上,它可能要经过好几个邮局。

img

在每个邮局,邮递员都会打开箱子,分拣邮件。邮递员查看打开箱子后露出的信封(下一个首部),发现这个信封是寄给 B 公司的。

img

然后邮递员把信封放进另一个可能不同的箱子里,这样信件就能到达前往 B 公司途中的下一个邮局。

img

这个过程在每个邮局都重复进行。箱子被打开,露出里面的信封。然后,信封被放进一个新的箱子里,发往下一个邮局。请注意,没有任何邮局会打开信封查看里面的信,因为它们不需要读信的内容。

img

最终,信件装在一个箱子里到达 B 公司,这一次,B 公司打开箱子和信封,露出里面的信。

主机和路由器中的多个首部

现在我们对主机和路由器有了全面的了解,让我们重新看一下当数据包在网络中经过多个跳段时,首部的封装和解封装过程。

首先,主机 A 接收消息,沿着协议栈向下,为第 7 层、第 4 层、第 3 层、第 2 层和第 1 层添加首部。现在,我们得到了一个被所有层的首部包裹的数据包。

第 1 层协议将这个数据包的比特沿着线路发送到前往目的地的第一个路由器。

img

这个路由器必须将数据包转发到下一个跳段,以便数据包最终到达主机 B。我们知道在全球网络中转发数据包是第 3 层的工作。因此,路由器必须解析数据包直到第 3 层。

路由器读取并解封装第 1 层和第 2 层的首部,露出下面的第 3 层首部。路由器读取这个首部来决定下一步将数据包转发到哪里。

img

现在,为了将数据包传递到下一个跳段,路由器必须再次沿着协议栈向下,封装新的第 2 层和第 1 层首部,然后将比特沿着线路发送到下一个跳段。

img

每个路由器都重复这个模式:解封装第 1 层和第 2 层以露出第 3 层首部,然后在将数据包发送到下一个跳段之前,封装新的第 2 层和第 1 层首部。请注意,没有任何路由器会查看第 3 层以上的协议,因为上层协议只由终端主机解析。

img

最终,数据包到达主机 B,主机 B 逐层解封装,依次是第 1 层、第 2 层、第 3 层、第 4 层、第 7 层。主机 B 成功接收了消息!

img

这种分层方案的一个结果是,每个跳段可以在第 2 层和第 1 层使用不同的协议。例如,第一个跳段可以通过有线传输,主机 A 和第一个路由器使用的初始第 2 层和第 1 层首部可以是有线协议的。相比之下,后面的某个跳段可以通过无线链路传输,该跳段两端的路由器使用的第 2 层和第 1 层首部可以是无线协议的。

img

更一般地说,我们说每一层只需要与同一层的对等实体通信。现在我们可以看到这在所有层中都得到了体现。在第 4 层和第 7 层,两台主机必须使用相同的协议来发送和接收数据包,主机的对等实体是另一台主机。

相比之下,在第 1 层和第 2 层,路由器必须与前一跳和后一跳的路由器使用相同的协议,这样路由器才能从前一跳接收数据包并向后一跳发送数据包。路由器的对等实体是路径上的相邻路由器。

img

总结一下:每个路由器解析第 1 层到第 3 层,而终端主机解析第 1 层到第 7 层。

img

(注:文档部分内容可能由 AI 生成)