# 分组生命中的一天(A Day in the Life of a Packet)

互联网的4层模型从应用层获取数据流，传输层将此数据流分解为数据段，并将其可靠地传送到另一台计算机上运行的应用程序。传输层将这些段作为网络层分组发送，网络层将这些分组发送给另一台计算机。让我们看看在实际中，web浏览器和服务器发送和接收的实际分组是什么样子。

## TCP字节流

![](https://1127374302-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdO26kEiXEDvJKjTRyadh%2Fuploads%2Fgit-blob-fad43c54e3f32b306b5e53921201d2f9e9327cc4%2F1.jpg?alt=media)

首先，让我们看看传输层。几乎所有的web流量都是通过TCP(传输控制协议)进行的。在它的典型操作中，有一个客户端和一个服务器，服务器侦听连接请求。要打开连接，客户端会发出连接请求，服务器会响应该请求。我不会详细介绍它是如何工作的，但事实证明，这种交换需要三条消息，称为“**三方握手**”。

握手的第一步是客户端向服务器发送一条“**同步**”消息，通常称为**SYN**。第二步是服务器响应“同步”消息，该消息也确认客户端“同步”，或“**同步和确认消息**”，通常称为**SYN-ACK**。第三步也是最后一步是客户端通过**确认**服务器的同步(通常称为**ACK**)来响应。因此，三方握手通常被描述为“同步、同步和确认、确认”或“**SYN、SYN-ACK、ACK**”。

![](https://1127374302-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdO26kEiXEDvJKjTRyadh%2Fuploads%2Fgit-blob-fe3611b637b2ced64ddb989cd60400d2eef220ff%2F2.jpg?alt=media)

回想一下，网络层负责向计算机传送分组，而传输层负责向应用程序传送数据。从网络层的角度来看，发送到同一台计算机上不同应用程序的分组看起来是一样的。这意味着要向另一个程序打开TCP流，我们需要两个地址。第一个是**网络协议地址(IP)**，这是网络层用于向计算机传送分组的地址。第二个是**TCP端口**，它告诉计算机软件要向哪个应用程序传送数据，web服务器通常在TCP端口80上运行。因此，当我们打开与web服务器的连接时，我们向运行web服务器的计算机发送IP分组，该服务器的目标地址是该计算机的IP地址，这些IP分组具有目标端口为80的TCP段。

## 流内部

![](https://1127374302-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdO26kEiXEDvJKjTRyadh%2Fuploads%2Fgit-blob-5d295d070d98f9fbcb8f04e44a6f05d04fdc9369%2F3.jpg?alt=media)

但是这些IP分组是如何到达目的地的呢？我们没有将我的客户端直接连接到服务器的线路。相反，我的客户端连接到一台中间计算机——一台路由器，此路由器本身连接到其他路由器。客户端和服务器之间的IP分组需要许多“跃点”，其中一个跃点是连接两个路由器的链路。例如，由于我的客户端位于WiFi网络上，因此第一个跃点是无线网络到WiFi接入点的。接入点与更广泛的互联网有有线连接，因此它沿着这个有线跳转发我的客户端分组。

路由器可以有许多连接它的链路。当每个分组到达时，路由器决定将其发送到哪个链路。路由器有IP地址，所以它也可能不转发分组，而是将其传送到自己的软件。例如，当你使用TCP登录路由器时，IP分组将发送到路由器自己的IP地址。

## 每跳内部

![](https://1127374302-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdO26kEiXEDvJKjTRyadh%2Fuploads%2Fgit-blob-6de5682789671bc1655166a57b6988ba75991cf1%2F4.jpg?alt=media)

路由器是如何做出这个决定的？它是通过一个叫做转发表的东西来实现的，如上图所示。转发表由一组IP地址模式和每个模式要发送的链路组成。

当分组到达时，路由器检查哪个转发表条目的模式与分组最匹配。它沿着该条目的链接转发分组。一般来说，“最佳”是指最具体的匹配。我将在关于最长前缀匹配的视频中更详细地描述这种匹配的工作原理。但是在这个简单的例子中，我们只考虑默认路由，上面表中的第一个条目。默认路由是最不特定的路由——它匹配每个IP地址。如果当分组到达时，没有比默认路由更具体的路由，路由器将只使用默认路由。

默认路由在边缘网络中特别有用。比如说，你在斯坦福大学，有一个路由器将你连接到更大的互联网。你的路由器将有许多特定的路由用于斯坦福网络的IP地址：“通过该链路向工程学校发送分组”，“通过该链路向图书馆发送分组。”但是如果目标IP地址不是斯坦福的，那么路由器应该将其发送到更大的互联网。

## 实践

现在让我们看看真实网络中的一些IP分组。我将从[www.brown.edu](https://www.brown.edu)请求一个网页，并使用一个名为Wireshark的工具向你显示所有分组。我们将看到我的web浏览器如何使用SYN、SYN-ACK、ACK三方握手打开到Brown web服务器的TCP连接，然后开始发出HTTP GET请求，服务器用数据响应该请求。一旦我们看到了我的客户端和布朗大学web服务器之间的分组交换，我将使用另一个名为traceroute的工具来观察这些分组通过Internet的路径。

### wireshark

所以首先我要启动wireshark。因为我的计算机正在使用许多网络应用程序并发送许多不同的分组，所以我将告诉wireshark仅使用端口80向Brown服务器显示属于TCP段的分组。这样，我们将只看到我生成的web流量。我还将告诉wireshark收听en1，这是我的Mac电脑给我的WiFi链路层起的名字。如你所见，我有许多可用的链路层，但让我们看看en1，因为这就是我连接到Internet的方式。

![](https://1127374302-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdO26kEiXEDvJKjTRyadh%2Fuploads%2Fgit-blob-03dd4591774ad0327a1e897ba43066686ba4b6c8%2F5.jpg?alt=media)

接下来，我将打开我的web浏览器并请求布朗大学计算机科学系的网页。这是我本科时去的地方，所以我喜欢了解系里的最新情况。你可以在wireshark中看到，加载此页面需要发送和接收大量分组！Wireshark向我显示了每个分组的时间戳、源IP地址、目标IP地址、它使用的协议、它的长度以及其他信息。看这第一个分组，它是从我的电脑(地址是192.168.0.106)到Brown CS web服务器(地址是128.148.32.12)。它将连接到TCP端口80——服务器上的超文本传输协议端口，我们可以从Info列中的> http字段中看到。这些分组是SYN分组——三方握手的第一步。

来看看前三个分组。第一个是从我的计算机到web服务器的SYN分组。第二个是从web服务器返回到我的计算机的SYN-ACK分组。第三个是从我的计算机返回到web服务器的ACK。这是三方握手！现在这两台计算机可以交换数据，你可以看到第一个分组是HTTP请求——我的计算机向web服务器发送GET请求。此GET请求的响应是三个分组——wireshark在收到第三个分组时显示响应，如信息为HTTP/1.1 200 OK的行所示。在这里，我们可以看到我如何从Brown的计算机科学服务器请求一个网页，通过三个IP分组创建一个TCP连接，用于三次握手，然后是更多的分组用于HTTP请求和响应。

### traceroute

这就是终端主机计算机在网络层交换分组时网络的样子。但是它在网络层中看起来是什么样子呢？这些分组要经过哪些跳数？要看到这一点，我将使用第二个工具，traceroute。Traceroute向你显示分组到目的地的跳数。因此，我们可以键入`traceroute www.cs.brown.edu`以查看通过Internet的路径。我将添加-w标志，它指定一个超时，超时时间为1秒。

![](https://1127374302-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdO26kEiXEDvJKjTRyadh%2Fuploads%2Fgit-blob-71d50c005809249f6aa88c13920b1a00d571b07e%2F6.jpg?alt=media)

分组的第一跳是到我的无线路由器，它的IP地址是192.168.0.1。正如你从下一跳看到的，我在家里——有一个有线调制解调器，互联网提供商是Astound。在此之后，分组需要另一个跳到IP地址为74.14.0.3的路由器。之后的一跳是加州旧金山的一个路由器，然后是圣何塞的几个路由器，sjc代表above.net，sanjose1代表level3.net。在sanjose1.level3.net之后，分组将在纽约的美国各地发送！它们通过纽约的一系列路由器——ebr、csw、ebr，然后在第13跳到达波士顿。波士顿离布朗所在的州很近。在oshean.org之后，我们看到了三颗星——这意味着有一个路由器不会告诉traceroute自己的身份。星星是traceroute显示它在等待回复，但回复超时的方式。在第20行，我们看到Brown的CS部门有一台路由器。在那之后，一切都被隐藏了——布朗的CS部门不想让你看到它的网络内部是什么样子。

![](https://1127374302-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdO26kEiXEDvJKjTRyadh%2Fuploads%2Fgit-blob-acd0d84a30ba8d2690c92b96520260675b501bbc%2F7.jpg?alt=media)

因为我们看不到布朗的网络服务器的路径，让我们试试另一个：麻省理工学院的计算机科学和人工智能实验室(CSAIL)。我们可以看到，分组沿着相同的路径到达波士顿，直到第15跳。通往布朗的道路在第15跳到达oshean，而通往麻省理工学院的道路在level3的网络中继续。在通往[www.csail.mit.edu](https://www.csail.mit.edu)的路径上，只有两个路由器被隐藏，第13和第19跳。我们可以看到[www.csail.mit.edu](https://www.csail.mit.edu)也被命名为[akron.csail.mit.edu](https://doraemonzzz.gitbook.io/cs-144-introduction-to-computer-networking-notes/unit1-internet-and-ip/1.5)，经过22跳之后，我的计算机上的分组到达了麻省理工学院的网络服务器。 看看来回的时间：我的分组到达麻省理工学院的网络服务器以及它的响应返回给我的时间不到90毫秒，或者说不到一眨眼的时间。

## 小结

我们现在已经看到了分组的生命周期，从应用程序级客户端web请求开始，通过Internet进行近20次跳跃以到达其目的地。对我来说，这是教这门课最好的事情之一：我们所呈现的一切都是你和我每天都要与之互动的——即使只是在看一个视频！在实践中很容易看到这些原则和想法，只需几个简单的工具，你就可以实时检查互联网的运行情况！
