斯坦福大学CSS144计算机网络一

前言

我整理了斯坦福大学CSS144计算机网络课程的精华笔记,在此分享给大家。 本系列长期更新,预计一周左右更新一章内容,共计九章。 斯坦福大学CSS144计算机网络课程可以从 Youtube观看链接 观看,也可以从 B站鬼谷良师搬运 观看。 建议大家结合视频,课件,以及我的精华笔记一起食用,事半功倍。 下面是第一章的精华内容: 我们将学到什么

  1. 了解 Web 浏览器等应用程序的工作原理,以及 Internet 如何在两台计算机之间传递数据包,我们将介绍三种网络服务模型
  2. 计算机网络的基本结构,比如什么是 4 层模型,以及每一层的职责。
  3. 计算机网络基本架构思想和原则
  4. 了解 TCP 是什么,IP 是什么。
  5. 了解 IP 地址、路由器如何查找 IP 地址。

1. 三种网络服务模型

三种典型的互联网服务:Web 服务,BitTorrent 大文件下载服务,Skype 语音聊天服务。

1.1 Web 服务

万维网使用 Http 工作,在 HTTP 中,客户端打开与服务器的连接并向其发送命令。最常见的命令是 GET,它请求一个页面。 Http 即超文本传输协议,Http 协议被设计为使用 ASCII 文本,以文档为中心的程序通信方式。

例如,如果我在浏览器中键入 http://www.stanford.edu/ ,浏览器会打开到服务器 www.stanford.edu 的连接,并发送一个 GET 请求以获取该站点的根页面。 服务器接收请求,检查它是否有效并且用户可以访问该页面,然后发送响应。 例如,如果服务器向 GET 发送 200 OK 响应,这意味着请求已被接受,并且响应的其余部分包含文档数据。

image.png

1.2 P2P 服务

课程将这种服务命名为 BitTorrent。BitTorrent 是一个允许人们共享和交换大文件的程序。 在 BitTorrent 中,客户端从其他客户端请求文档。为了使单个客户端可以同时向许多其他客户端请求,BitTorrent 将文件分解为称为片段的数据块。当客户端从另一个客户端下载完整的片段时,它会告诉其他客户端它拥有该片段,以便他们也可以下载它。我们将这些协作客户的集合称为。 当客户端想要下载一个文件时,它首先必须找到一个叫做 torrent 文件(种子文件)的东西。通常,我们使用万维网找到它并使用 HTTP 下载它。这个 torrent 文件描述了有关您要下载的数据文件的一些信息。它还告诉 BitTorrent 关于该种子的跟踪器(Tracker)是谁。Tracker 是一个节点,它清楚哪些客户端是群内成员。 最后您的客户端再次通过 HTTP 联系跟踪器,以请求其他客户端的列表。您的客户端与其中一些客户端建立连接并开始请求文件的各个部分。 image.png

1.3 中继服务

课程将这种服务命名为 Skype,它代表着 语音、聊天服务。Client(终端)与 Server 不同,Client 一般藏在 NAT 后面。什么是 NAT?NAT 也可叫做网络地址转换器,比如家里的无线路由器就是 NAT,当手机连接到 Internet 时,它位于 NAT 后面。 关于 NAT 只需要记住:如果客户端在 NAT 后面,那么它可以轻松连接到 Internet,但 Internet 上的其他节点不能轻松连接我们的客户端。 比如,ClientA 请求 ClientB,ClientB 位于 NAT 后,那么 ClientA 无法直接请求到 ClientB,需要通过中继服务器代理。由于在此之前,ClientB 已经主动与中继服务器建立了双向连接,所以在中继服务器告知 ClientB 来自 ClientA 的请求后,ClientB 主动建立与 ClientA 的连接,这种方式也叫做反向连接。 image.png 那么如果 ClientA 也位于 NAT 之后呢?以上文为基础,该问题很好解决,就是 ClientA 也主动建立与中继服务器的连接。 image.png

1.4 小总结

至此,我们已经看到了网络应用程序最常见的通信模型:可靠的双向字节流。这允许在不同计算机上运行的两个程序交换数据。它将整个网络抽象为一个简单的读/写关系。 我们体验了 3 个示例:万维网、BitTorrent 和 Skype。

  1. 万维网是客户端-服务器模型。客户端打开与服务器的连接并请求文档,服务器响应文档。
  2. BitTorrent 是一种点对点模型,成群的客户端打开彼此的连接以交换数据片段,从而创建一个密集的连接网络。
  3. Skype 是两者的混合体。有时客户端无法直接打开连接,可以通过中继服务器建立连接。

2. 网络的四层模型

2.1 链路层

链路层的工作是将数据包通过一系列的路由器转发,最终到达目标机器。 image.png

2.2 网络层

网络层的工作是通过 Internet 端(主机)到端(主机)传输数据包,它利用了链路层的服务,且完全不关心链路层的实现方式。

数据包是网络中重要的基本构建块,它描述了数据内容、以及去向和来自何处。

image.png 下图描述了源机器的数据包是如何一步步到达目标机器的: image.png

2.3 传输层

最常见的传输层协议是 TCP,TCP 确保 Internet 一端的应用程序发送数据成功,如果网络层丢弃了一些数据,TCP 将重新传输它们。除此之外,TCP 也确保数据包的传输的正确顺序。 传输层为应用层提供服务,在网络层服务的基础上,为应用程序提供正确顺序的数据传递。

2.4 应用层

应用层调用传输层提供的 API,为应用程序提供网络服务。应用层之间使用 Http 协议,常见场景是使用 Http Get 命令以 ASCII 字符串以及所请求页面的 URL 的形式发送数据。

2.5 七层 OSI 模型

image.png

3. IP协议

Network 层是网络中最重要的一层,所有应用程序都使用 IP 协议来发送和接收数据包,没有别的选择,正因如此,IP 协议也被称作网络中的“瘦腰”。 IP 数据报由一个报头和一些数据组成。当传输层有数据要发送时,它会将一个传输段交给下面的网络层。我们从下图可以感受到网络数据包的层层套娃。 image.png

3.1 IP 协议三大特征

3.1.1 IP 是不可靠的。

IP 不承诺将数据包传送到目的地。 它们可能会延迟交付、乱序交付或根本不交付。 数据包可能会在此过程中被复制,例如被行为不端的路由器复制。 IP 确实承诺仅在必要时丢弃数据报。 例如,路由器中的数据包队列可能由于拥塞而被填满,迫使路由器丢弃下一个到达的数据包。 IP 不会尝试重新发送数据——事实上,IP 不会告诉源数据包已被丢弃。 它完全不维护与通信相关的任何状态。

3.1.2 IP 试图防止数据包永远循环。

每个路由器都包含一个转发表,告诉它将匹配给定目标地址的数据包发送到哪里 由于 IP 路由器在 Internet 上逐跳转发数据包,因此路由器中的转发表可能是错误的,从而导致数据包开始循环并沿着相同的路径循环。 IP 只需在每个数据报的报头中添加一个跳数字段。它被称为生存时间,或 TTL 字段。它以 128 之类的数字开始,然后被它通过的每个路由器递减。如果它达到零,IP 断定它必须陷入循环并且路由器丢弃数据报。

3.1.3 如果数据包太长,IP 会将数据包分段。

例如,以太网只能传输长度小于 1500 字节的数据包。 如果应用程序要发送的字节数超过 1500 字节,则必须在发送 IP 数据报之前将其分段。

3.2 认识 IPv4 数据包

image.png

  1. Source IP Address 源 IP 地址。
  2. Destination IP Address 目标 IP 地址。
  3. Protocol ID 协议ID,比如Protocol ID = 6,那么它告诉我们数据包包含一个 TCP 段。互联网号码分配机构 (IANA) 定义了超过 140 种不同的协议 ID 值,代表不同的传输协议。
  4. Version 版本告诉我们哪个版本的 IP ,合法值为 IPv4 或 IPv6。
  5. Total packet Length(包的总长度)可以达到 64kBytes,包括包头和所有数据。
  6. TTL 帮助我们防止数据包意外地在 ntwork 中永远循环,每个路由器都需要减少 TTL 字段。如果它达到零,路由器应该丢弃数据包。
  7. 有时一个数据包对于要发送的链接来说太长了。 Packet ID、Flags 和 Fragment Offset 都有助于路由器在需要时将 IP 数据包分割成更小的独立数据包。
  8. Type of Serive(服务类型)字段向路由器提示该数据包的重要性。
  9. Header Length(标头长度)字段告诉我们标头有多大。
  10. 最后,Checksum(校验和)是根据整个报头计算出来的,以防报头损坏。

4. 数据包的一生

4.1 TCP 如何建立连接

一个客户端请求连接服务器是非常典型的场景,我们可能会想当然的认为,这是一个两步操作:“请求”&“响应” image.png 事实上这种交换需要三个消息,称为“三次握手”。

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

我们可以使用软件Wireshark来直观感受 TCP 握手的过程,如图所示,我们用浏览器访问 http://cs.brown.edu/ ,其 IP 地址为 128.168.32.12,可以看到有来自128.168.32.12[SYN,ACK],也有来自我们本地的[SYN][ACK],也能看到 HTTP 的 GET 请求等等。

注意应用层协议是 http,不是 https(https的内容后面会讲到)

image.png

4.2 TCP 与 IP 分别干了什么活

网络层仅负责将数据包传递给计算机,而传输层负责将数据传递给应用程序。 从网络层的角度来看,发送到同一台计算机上不同应用程序的数据包看起来是一样的。 这意味着要做到两个应用程序交换数据,我们需要两个地址。 第一个是 Internet 协议地址,是网络层用来将数据包传送到计算机的地址。 第二个是 TCP 端口,它告诉计算机软件将数据传送到哪个应用程序。 Web 服务器通常运行在 TCP 端口 80 上。因此,当我们打开与 Web 服务器的连接时,我们会将 IP 数据包发送到运行 Web 服务器的计算机,其目标地址是该计算机的 IP 地址。 这些 IP 数据包具有目标端口为 80 的 TCP 段。 image.png

4.3 路由器如何转发数据包

现在我们知道 Client 和 Server 的通信要经过路由器群。路由器如何转发数据包?它通过称为转发表的东西来实现,如下图所示。转发表由一组 IP 地址模式和为每个模式发送的链接组成。 当数据包到达时,路由器会检查哪个转发表条目的模式与数据包最匹配。它沿着该条目的链接转发数据包。通常,“最佳”意味着最具体的匹配。(关于最佳匹配的算法在第8小结做了详细介绍) image.png 可以使用traceroute命令来感受 路由跳转,每个数字就代表一跳,* * *意味着路由器屏蔽了信息。

haoyufei@Diablo ~ % traceroute www.cs.brown.edu
traceroute to www.cs.brown.edu (128.148.32.12), 64 hops max, 52 byte packets
 1  192.168.0.1 (192.168.0.1)  17.093 ms  9.828 ms  9.473 ms
 2  218.17.162.129 (218.17.162.129)  18.666 ms  18.658 ms  20.429 ms
 3  * * *
 4  218.17.52.42 (218.17.52.42)  18.277 ms
    61.144.236.181 (61.144.236.181)  20.215 ms
    58.60.235.21 (58.60.235.21)  7.534 ms
 5  1.186.37.59.broad.dg.gd.dynamic.163data.com.cn (59.37.186.1)  9.161 ms
    61.146.247.193 (61.146.247.193)  19.337 ms  15.221 ms
 6  125.176.37.59.broad.dg.gd.dynamic.163data.com.cn (59.37.176.125)  23.425 ms  20.298 ms
    117.176.37.59.broad.dg.gd.dynamic.163data.com.cn (59.37.176.117)  19.342 ms
 7  183.56.65.69 (183.56.65.69)  9.476 ms
    14.147.127.93 (14.147.127.93)  20.166 ms
    14.147.127.89 (14.147.127.89)  18.483 ms
 8  202.97.94.138 (202.97.94.138)  17.867 ms
    202.97.94.126 (202.97.94.126)  18.930 ms
    202.97.94.142 (202.97.94.142)  17.630 ms
 9  202.97.12.5 (202.97.12.5)  11.727 ms *
    202.97.94.106 (202.97.94.106)  25.900 ms
10  202.97.51.110 (202.97.51.110)  175.015 ms
    202.97.51.98 (202.97.51.98)  182.644 ms
......

5. 网络的三大基本原理

网络的设计原则:分层,封装和数据包交换。

5.1 分组交换

上面我们提到了路由器根据转发表来转发数据包,相比较于 IP 数据包内预定路由器转发线路,这是有很多好处的,比如

  1. 没有信息安全问题,Hacker 可以通过修改 IP 包来骗过路由器将数据包发送到非法地址( 如果 IP 数据包内预定路由器转发线路)
  2. 没有性能问题,路由器可以为每个数据包做出单独的本地决策,否则的话,在发送 IP 之前计算 Router 线路是一个庞大的工作量。
  3. 资源利用率高,任何一个 IP 包都无法独占某个路由线路。

假如 A 要给 E 发送一个数据包 P,但这个数据包有点大,需要分成三组,例如分成 p1、p2、p3 三个更小的数据包。 这时 A 直接把小数据包丢给附近的路由器,然后 A 就不管了,例如 A 把 p1 丢给了 B,这个时候 A 就不再管 p1,当 B 收到 p1 这个完整的小数据包之后,B 再丢给 E。 分组交换有几个特性:

  1. 存储特性,B 必须收到完整的 p1 数据包后才能转发。
  2. 非实时性,由于 A 把数据包丢给 B 之后就不管了,B 什么时候会把 p1 转发出去,谁也不知道,B 绕几个圈子再发给 E 也是有可能的。
  3. 通信阻塞,可能会有很多路由器把数据包丢给B,这个时候就会造成通信阻塞,可能 p1 在排队等待 B 来发送。
  4. 丢包,由于 B 路由器的容量是有限的,如果有太多的数据包丢给它,它可能会容纳不下,这时候就可能会出现丢包的情况。
  5. 重复数据,再者,由于 p1、p2、p3 数据包都有文件头,里面都包含了 A 和 E 的一些信息,当然还有其他的信息。

5.2 分层

可以说任何复杂的计算机系统,甚至是现实世界中的系统(比如邮政,物流系统)都是分层的,分层意味着我们将大的复杂问题拆解成一个个易于处理小问题,分层意味着模块化,意味着可以分离每层的关注点和责任,意味着每层可以独立发展与优化。 我们拿最熟悉的编程举例,Java 等语言很好的为程序员隐藏了计算机底层细节,我们只需要专注于编写 Java 代码,然后将代码交给下层的编译器,编译器生成目标代码,然后将其传递给链接器,链接器将编译的目标文件和库链接在一起生成一个可执行文件,最终机器执行代码。 分层让编译器专注于词法分析,让链接器专注于有效地将对象拼接在一起,双方都不必担心对方的工作,并且每个人都可以改进,升级。 image.png

5.3 封装

封装是指我们将网络各层数据以一种灵活的方式组装成数据包每个数据包都包含来自多个层的数据。 假设我们正在使用计算机通过 WiFi 浏览网页。我们的 Web 浏览器会生成一个 HTTP GET 请求。此时 HTTP GET 请求是 TCP 段的有效负载,同时此 TCP 段是 IP 数据包的有效负载。这个封装了 TCP 段和 HTTP GET 的 IP 数据包是 WiFi 帧的有效负载。 数据包最外层的封装格式是WiFi帧,里面是IP包,里面是TCP段,里面是HTTP GET。 image.png

5.3.1 递归封装

我们可以更灵活的封装数据包,比如我们在使用 TLS 时,实际上是将我们的 IP 包放入一个 TLS 段内,TLS 保护信息并使其保密。这个 TLS 会话是在一个 TCP 流内,这意味着我们将 IP 包放入了 TCP 包内。 image.png

6. 字节顺序和数据包格式

6.1 什么是字节序

字节序,又称端序尾序(英语中用单词:Endianness 表示),在计算机领域中,指电脑内存中或在数字通信链路中,占用多个字节的数据的字节排列顺序。 字节的排列方式有两个通用规则:

  • 大端序(Big-Endian)将数据的低位字节存放在内存的高位地址,高位字节存放在低位地址。这种排列方式与数据用字节表示时的书写顺序一致,符合人类的阅读习惯。
  • 小端序(Little-Endian),将一个多位数的低位放在较小的地址处,高位放在较大的地址处,则称小端序。小端序与人类的阅读习惯相反,但更符合计算机读取内存的方式,因为CPU读取内存中的数据时,是从低地址向高地址方向进行读取的。

我们举个例子就很好懂,比如我们想在内存中存放整型168496141需要 4 个字节,这个数值的对应的16进制表示是0X0A0B0C0Dimage.png

X86 计算机使用小端序,ARM 计算机使用大端序。

6.2 为何要有字节序

很多人会问,为什么会有字节序,统一用大端序不行吗?答案是,计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。在计算机内部,小端序被广泛应用于现代 CPU 内部存储数据;而在其他场景,比如网络传输和文件存储则使用大端序

7. 子网掩码

子网掩码告诉设备哪些 IP 是本地上的,哪些 IP 是网络上的。送往网络的数据包需要通过路由器,而送往本地的则不需要。 子网掩码被写成一连串的“1”,比如 255.255.255.0 的前 3 个八位二进制数字为“1”,这意味着前 24 位相同的两个 IP 地址处于同一网络中。同理,255.255.252.0 意味着前 22 位相同的 IP 处于同一网络,255.128.0.0 意味着前 9 位。同时我们也可以很容易的得出一个结论:较小的子网掩码意味着较大的网络

两台机器的 IP 地址分别和子网掩码进行按位与运算,如果运算结果相等,则两台机器在同一网络中。

我们可以用 ifconfig 命令直观感受下子网掩码,打开终端输入 ifconfig 命令,我们可以看到 IP 为 192.168.0.173,我们的网络掩码(子网掩码)为 0xffffff00,这是十六进制的 255.255.255.0,这意味着以 192.168.0 开头的 IP 地址与我们处于同一个本地网络,二者之间发送数据包不需要通过路由器。

......

en0: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
	options=6463<RXCSUM,TXCSUM,TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>
	ether bc:d0:74:38:80:fe
	inet6 fe80::184e:651c:6716:6ec7%en0 prefixlen 64 secured scopeid 0xe
	inet 192.168.0.173 netmask 0xffffff00 broadcast 192.168.0.255
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active

......

7.1 历史上的 IP 地址结构

历史上的 IP 地址分为网络部分和主机部分,根据网络部分和主机部分长度的不同分为三类: image.png 地址的网络部分为管理域,管理域可大可小,大到国家,小到学校,都可以作为管理域,比如 A 类地址,7 位网络位,24位主机位,可以表示 128 个网络,1677W 个 IP 地址。

7.2 现代的 IP 地址结构

我们很容易发现,上面的网络位只有三种不够灵活,所以如今的 IP 地址进化为无类域间(CIDR),CIDR 允许任意长度的网络位(也就是子网掩码的长度),比如:171.64.0.0/16,其子网掩码的长度为 16。 发放 IP 地址的权威机构是 IANA,它向各大互联网区域注册机构(Regional Internet Registries,RIR)发放 /8 子网,比如美国的 RIR 是 ARIN,各个 RIR 自己决定如何将 /8 子网分割为更小的块。

8. 路由转发算法

之前我们提到了路由器根据路由表转发数据包,路由表中存有很多路由地址,如何知道选择哪个路由地址是最优解呢?这时就用到了路由转发算法,也叫做最长前缀匹配算法(LPM)。 路由表如图所示,其中 x 代表通配符。 image.png 匹配算法以最具体为目标,什么意思呢?我们举个例子:假设我们有一个路由表如下所示,此时有一个数据包的目标地址为 171.33.13.14,同时匹配上了 0.0.0.0/0 和 171.33.0.0/16,此时路由器会选择转发到后者,因为后者子网掩码前缀为 16 位,比 0 位更长,更具体。

image.png

9. ARP 协议

现在我们已经知道,数据包由链路层运输,其第一步就是将数据包发送到链路中路由器的物理地址(也叫MAC地址)。如果不知道路由器的物理地址怎么办?ARP 就是用来解决这个问题的:ARP 可以发现与其直接连接的 MAC 地址。

注意 IP 地址与 MAC 地址是两回事,IP 地址描述了“此主机”,而 MAC 地址描述了“此网络设备” MAC 地址长度为 48 位,用 6 组十六进制表示,比如 00:13:72:4c:d9:6a

ARP 形成了一个 IP 地址 与 Mac 地址的映射关系。它是一种简单的请求-应答协议,每个节点都保留 IP 地址与 Mac 地址映射关系的缓存。如果节点需要将数据包发送到它没有映射到 IP 地址,就会**广播(ff:ff:ff:ff 地址)**发送一个请求:“谁有 xxx 这个 Mac 地址”,具有该 Mac 地址缓存的节点就会做出响应。 我们举个例子,假设我们有一台 Client(IP:192.168.0.5)位于 gateway 网关(IP:192.168.0.1)下,此时 Client 想要把数据包发送到 Internet,第一步就是要把数据包发送到 gateway,如果此 Client 不知道 gateway 的 MAC 地址,就需要用 ARP 来请求其他“知道 gateway MAC 地址”的 Client 来帮忙。

image.png

9.1 详解 ARP 数据包

ARP 数据包有 10 个字段。

  1. Hardware 字段说明此请求/响应应用于哪个链路层
  2. Protocol 字段说明此请求/响应所针对的网络协议
  3. Hardware、Protocol length 字段说明链接层、网络地址的字节数
  4. Opcode 说明该数据包是请求操作还是响应操作,1 代表请求,2 代表响应。
  5. Source hardware address、Source protocol address、Destination hardware address、Destination protocol address 四个字段用于请求和指定映射
  1. 所有数据采用大端序,比如 Opcode = 15,那么它将存储为 0x000f。
  2. Protocol = 0x0800 时对应 IP 协议,此时 Source protocol address 的值为 IP 地址,其他涉及到 Protocol 的字段以此类推。

image.png


参考: 什么是电路交换和分组交换 什么是大端序和小端序,为什么要有字节序