UCB CS168笔记 Chapter 1 Introduction

本文最后更新于 2026年4月2日 上午

前言

对于这门课的简短的评价在[这篇Blog](CS168 SP25 Project2 Distance-Vector Routing笔记 - wendaining)里面有写过,这里不再赘述。

主要是回顾 Project 2 的时候,发现自己 Routing章节的知识已经快忘了,不甘于此,遂打算从第一章开始重新梳理笔记。

Introduction to the Internet

What is the Internet?

Internet != World Wide Web

Web: 构建在Internet上的Applications,通过浏览器可访问

除了网络应用之外,其他应用程序同样可以利用互联网基础设施。非网络应用的例子包括 Zoom 或在线游戏,甚至是物联网(IoT)设备。

Zoom 之所以不被归类为传统的 Web 应用,主要基于以下几个技术维度:

1. 运行环境与依赖项 (Runtime Environment)

  • Web 应用: 运行在 浏览器(如 Chrome, Safari, Edge)内核沙盒中。它们依赖 HTML, CSS 和 JavaScript,并受限于浏览器的安全策略。
  • Zoom(客户端): 是一个 原生应用(Native Application)。它直接运行在操作系统(Windows, macOS, iOS, Android)之上。它可以直接调用系统的底层资源,如 CPU 的硬件加速、高级音频驱动和复杂的内存管理,而不需要通过浏览器这个“中间商”。

2. 通讯协议的差异 (Protocols)

这是最核心的技术区别:

  • 标准 Web 应用: 主要使用 HTTP/HTTPS 协议。这是一种“请求-响应”模式,虽然现在有 WebSocket,但其根基仍是 Web 标准。
  • Zoom: 为了保证极低延迟的音视频传输,Zoom 使用了大量的 UDP(用户数据报协议)
    • HTTP 通常基于 TCP,追求数据的 100% 准确(哪怕慢一点)。
    • 实时视频通话追求的是“快”,丢一两个像素包没关系,但不能卡顿。Zoom 拥有自己私有的传输协议和编解码技术,这些在标准浏览器环境下很难达到同等的极致性能。

Why is Internet Interesting?

互联网带来了许多与传统计算机科学领域不同的新挑战。例如,与理论领域不同,我们没有互联网的形式化模型。与硬件领域不同,我们没有可衡量的性能基准。

对于计算机网络,代码“可运行”是完全不够的,编写的代码必须能够扩展到数十亿用户,编写的代码还必须与不同运营商的商业关系保持一致。

网络架构更多地是关于思考设计,而不是证明定理或编写代码。它更多地是关于考虑权衡,而不是满足特定的基准。它更多地是关于设计实用的系统,而不是寻找最优的设计。互联网并非最优,但成功地平衡了广泛的目标。

The Internet is Federated

即:每个ISP独立运作,但是为了构建Internet,需要合作,这也就引出了Protocols

The Internet is Scalable(可扩展的)

由于Internet is federated, 我们只需专注于the interconnecting of different operators,同时允许了我们用多样化的技术构建互联网(有线 / 无线 / 光纤 / 海底电缆等等等),这使得互联网具有一个巨大的规模。

互联网的全球规模意味着我们的系统和协议需要以异步方式运行。数据无法超越光速传播(且通常远慢于此)。假设你向地球另一端的服务器发送一条消息,当消息抵达时,你的 CPU 可能已执行了数百万条额外指令,而你发送的消息或许早已过时。

互联网的规模意味着即使发送单条消息也可能需要与众多组件(如软件、交换机、链路)交互。其中任何组件都可能发生故障,而我们甚至可能无法感知故障的发生。若确实出现故障,可能需要很长时间才能获知这个坏消息。互联网是首个必须为大规模故障而设计的系统,其诸多理念后来也被其他领域所采纳。

简单理解就是一条route上有太多的设备,就算故障率很低,根据二项分布也容易得出不发生故障的概率是很低的,故障是必须被考虑的。

Protocols

就是一套通信实体之间互相交互的约定俗成

这些协议涉及消息交换的格式规范,以及实体如何响应这些消息。

You’ll sometimes see the acronym RFC (Request For Comments) when we mention a protocol. Many standards are published as RFC documents that are eventually widely accepted, though not all RFCs end up adopted. RFC documents are numbered, and sometimes protocols are referred to by their RFC number. For example, “RFC 1918 addresses” refers to addresses defined by that particular document.

Layers of the Internet

Layer 1: Physical Layer

这一块UCB CS168课程基本上是忽略了,我将后续把课内的课程对于物理层讲解的笔记梳理好复制到这里。

此处只需先理解物理层就好像是构建一个bit-pipe,一种在空间中传输bits的方式。

在物理层的基础上(有了在空间中传输bits的方式),就以此来链接hosts。

在互联网中,一条链路连接着两台机器。这条链路可以采用任何类型的技术(有线、无线、光纤等)。如果我们用链路连接起一批附近的计算机(例如UCB的所有计算机),我们就得到了一个局域网。

在Link Layer:

  • 我们还可以将比特分组为称为数据包的数据单元(在这一层有时也称为帧),并定义每个packet在物理信号中的起始与结束位置(相当于就是给数据包加上header和trailer)
  • 还可以处理诸如多人同时使用同一根cable发送数据的问题

Layer 3: Internet Layer

Link Layer只能负责连接局域网内的所有人,但是如果两个局域网之间想要通信,就略难办。

一种方法是搞出来一个全连接图,但是这考虑到互联网的庞大,显然太不现实了

一个更合理的做法:每个网络引入一个“邮局”,然后把邮局连接起来:

在互联网中,接收和转发邮件的邮局被称为交换机或路由器。

如果在routers之间建立额外的连接,即可构建local networks;通过进一步扩展连接,我们得到Internet

Routing 单元,我们将重点回答这样的问题:如何在网络中找到路径,以及当路由器收到一个packet的时候,它将如何知道将数据包转发到哪里?

同时,需要保证链路有足够的容量来承载数据,这是Congestion Control 单元的重点。

本课程还将研究 Internet Service Providers (ISP) such as 中国移动、中国电信

Network of Networks

Internet 经常被描述成 Network of Networks。众多小型 local networks 各自独立运作,内部事务由内部管理,随后所有 local networks 相互连接,构成 Internet。

不同的 Network 可能使用不同的 Link Layer technology,比如说有些用有线以太网,有些用光纤,有些用无线蜂窝技术。

  • Link Layer研究的是如何通过在这个网络内的link发送packets
  • Internet Layer研究的是如何将packet发送到Internet的任何地方,在这个过程中packet可能沿着多种不同类型的link进行传输

区分终端主机和和路由器/交换机:

  • end host是通过互联网进行通信的机器
  • 交换机/路由器是不发送或接收信息,其存在是为了帮助end hosts之间互相通信的机器

Layer of Abstraction

其实就是互联网的分层设计原则,为什么要这样?

带一点个人的理解:计算机领域整个就是一个巨大的封装

这种分层、网络互联方法的一个主要优势在于,每个网络都可以自行决定如何传输数据。例如,当数据包在互联网上跳转时,某些链路可能使用无线技术,而其他链路可能使用有线技术。底层协议可以在不同的跳转中变化,而Internet Layer的Protocols仍然有效。

Layer 3: Best-Effort Service Model

Layer 3 (Layer of Internet)现在有两大问题需要解决,这里我们说第一个问题:

网络会向用户提供怎样的服务模型?所谓服务模型,可以理解为网络和用户之间的契约,这个契约描述了网络支持与不支持的功能。

实际服务模型的例子可能包括:网络保证数据被送达。或者,网络保证数据在一定时间限制内被送达。或者,网络不保证送达,但承诺在失败时报告错误。

但是,Internet只支持 Best-Effort 尽力而为的服务模型,如果你通过第三层发送数据,互联网会尽力将其送达,但不保证数据一定会被送达。互联网也不会告诉你传输是否成功。

为什么设计者选择了如此薄弱的一个服务模型?一个主要原因是,满足这些较弱需求的网络更容易构建。

Layer 3: Packets Abstraction

为了传输大文件,我们引入“数据包 packet”这一抽象概念。我们以某种方式将数据拆分成数据包,并独立地通过网络发送数据包。

有了数据包这一抽象概念,我们现在可以观察数据包在网络中传输的生命周期。发送方将数据拆分为独立的数据包。数据包沿着链路传输并到达交换机。交换机会将数据包转发至目的地,或是转发给更接近目的地的另一台交换机。数据包在一台或多台交换机之间跳跃,每台交换机都将其向目的地更近一步转发,直至最终抵达目标。需要注意的是,由于采用尽力而为的传输模型,任何交换机都可能丢弃数据包,因此无法保证数据包实际到达目的地。

Layer 4: Transport

第三层的两个问题:大数据需要分成数据包、IP协议是Best-Effort的。

为了解决这两个问题,引入Transport Layer。

Transport Layer的功能:引入了一种额外的协议,用于重新传输丢失的packet,将data分割成packets,对于乱序到达的packets进行排序,etc.

这一层的协议将数据包再一次抽象,使我们能够不再以数据包为单位进行思考,转而开始以流(即两个端点之间交换的数据包序列)为单位进行思考。

Layer 7: Application

也没什么好说的,就是再封装了一层,让应用程序访问网络更便捷。

注意:你可能已经注意到我们跳过了第 5 层和第 6 层。在 20 世纪 70 年代,当这些层级首次被标准化时,设计者认为这些层级是必要的,但在现代互联网中它们已经过时了。如果你好奇的话,会话层(第 5 层)原本应该将不同的数据流组合成一个会话(例如加载各种图像和广告以形成网页),而表示层(第 6 层)原本应该帮助用户可视化数据。如今,这些层级的功能大多在第 7 层中实现。

其实就是 OSI Model 和 TCP / IP Protocol Stacks 简化模型的区别。

Headers

Why Do We Need Headers?

交换机在收到这一串bits的时候并不知道如何处理,于是我们需要attach additional metadata,这些额外的metadata被称为headers,其余的部分被称为payload

Network Infrastructures 只阅读 Headers 来决定如何传输信息,而不阅读 payload。

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

Headers are Standardized

这个其实很好理解,互联网上那么多设备,肯定要达成一致的。

What Should a Header Contain?

  • 目标地址
  • 源地址——技术上分析非必须,但是为了接收方向发送方回复
  • checksum,确保没有损坏
  • 其他metadata,比如数据包的长度

Multiple Headers

使用邮政的类比:假设 A 公司的老板想给 B 公司的老板写一封信:

总结:发送的时候自顶向下逐层封装

对面接受的时候,也是一层一层解包的,对应的图就不放过来了。

请注意,随着我们向更低的抽象层移动,我们在数据周围包裹了更多的头部信息。随后,当我们向更高的抽象层移动时,我们逐层剥离了数据的封装。

每一层只需理解自身的头部信息,并在某种意义上与同层的对等实体进行"通信"。当秘书 A 在信封上写下姓名时,这是为了让秘书 B 阅读(而非邮递员或上司)。

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

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

Addressing and Naming

上文提到 Header 包括“接收方的地址”,那么,究竟什么是地址?

当我们更深入地研究不同网络层级时,会发现各层级采用不同的寻址方案。互联网中的不同层级采用最适合该层级的寻址方案。

如,有时主机会通过人类可读的名称来指代(如 www.google.com)。有时,同一主机又通过机器可读的 IP 地址来标识(如 74.124.56.2),这串数字以某种方式编码了服务器的位置信息(若服务器迁移,该地址可能变更)。还有些情况下,同一主机可通过其硬件 MAC 地址来识别,这个地址是永久不变的。

Layers at Hosts and Routers

除了两个终端主机外,还有路由器将数据包通过多跳转发至目的地。

那么,我们的分层和 Header 的理念,是如何在这些设备之间交互的?

路由器只实现前三层,因为路由器不需要考虑呈现网页(obviously),路由器也不需要关心可靠性(因为best-effort)。

总结来说:较低的 3 层在所有地方都得到实现,但最高的 2 层仅在终端主机上实现。

Multiple Headers at Hosts and Routers

简单来概括:之前说有 Multiple Headers,自顶而下层层包装。但是经过路由器的时候,由于路由器只关心前三层,路由器只会拆掉到 Layer 3 Header 为止,读取信息之后再重新包装。

这个过程不断重复。

这种分层方案的一个结果是,每一 hop 都可以在第 2 层和第 1 层使用不同的协议。例如,第一跳可能通过有线方式发送,主机 A 和第一个路由器使用的初始第 2 层和第 1 层报头可以用于有线协议。相比之下,后续的一跳可能通过无线链路发送,该跳两端路由器使用的第 2 层和第 1 层报头可以用于无线协议。

这其实更体现了每一层只需要与同层的对等实体通信的说法。两端的 end hosts 在 Transport Layer 和 Application Layer 必须使用相同的协议进行通信;前后两跳的路由器在 Physical Layer 和 Transport Layer 也必须使用相同的协议进行通信。

Network Architecture

Design Paradigms

本节的重点在于上至下地审视互联网,并分析其设计中的总体架构选择。

有些设计很早就诞生了,有些设计至今仍有争议,互联网仍在不断发展。

在最初的互联网中,交换机被刻意设计为"傻瓜式"设备,仅转发数据而不进行解析。然而,在现代互联网中,攻击者可能试图通过洪泛无用数据来压垮交换机,因此交换机可能需要具备检测此类攻击的能力。早期提出"傻瓜式"基础设施范式的互联网设计者并未考虑到这种安全隐患。

Narrow Waist

第三层只有一个协议。这就是实现互联网连接的 "Narrow Waist"。最终,互联网上的每个人都必须同意使用 IP 协议,以便数据包能够在互联网上传输。

Demultiplexing

接收端在收到报文后,根据Header的标识,将数据分发给正确的套接字(Socket),从而到达对应的应用程序。

术语“套接字”指的是操作系统中的一种机制,用于将应用程序连接到操作系统内的网络协议栈。当应用程序打开一个套接字时,该套接字会与一个逻辑端口号相关联。当操作系统接收到数据包时,它会使用端口号将该数据包导向相关联的套接字。

这里可以看出来,选TCP还是UDP没说清楚;选哪个应用程序是靠端口标识的。

注意这张图里面OS的地位。

End-to-End Principle

这里其实就是一个概述,大概复制黏贴一下原文吧,后面有专门的一章讲这个。

引用端到端原则指导着关于网络应实现与不应实现哪些功能的讨论。该原则涵盖面很广,应用场景众多,但我们将重点关注这个问题:我们应在网络中实现可靠性(第...

端到端原则指导着关于网络应实现与不应实现哪些功能的讨论。该原则涵盖面很广,应用场景众多,但我们将重点关注这个问题:我们应在网络中实现可靠性(第 4 层),还是仅在终端主机上实现?

如果我们在网络中实现可靠性,互联网会是什么样子?与之前的设想不同,现在每个路由器除了理解第 1、2、3 层外,还必须理解第 4 层。

在这种新的架构下,中间路由器必须可靠地将数据包发送至下一跳。它必须确保下一跳接收到了所有数据包,若未收到,路由器必须重新发送任何丢失的数据包。主机不再检查是否所有数据包都已接收,而是依赖网络来确保所有数据包都被送达。

在这种方法中,主机必须信任网络。如果其中一个路由器出现故障并丢弃数据包,主机实际上对此无能为力。

另一种方法是端到端方法,即不在网络中实现可靠性,而是强制两个终端主机来确保可靠性。路由器可以丢弃数据包,而由终端主机负责验证所有数据包是否已接收。

在端到端方法中,由终端主机实现可靠性,控制权掌握在主机手中。主机仍可能存在缺陷并丢弃数据包,但这一次,主机有能力自行修复这些缺陷。更广泛地说,如果你在编写代码,最好能自己控制功能的正确性,而不是依赖可能出错且你无法修正其错误的他人。

考虑到这一对比,如果我们采用第一种方法,即依赖网络本身确保正确性,那么当网络存在缺陷时,我们实际上无法保证完美的可靠性。最终,终端主机很可能还是需要进行端到端的检查(就像第二种解决方案那样)。

总而言之:某些应用需求必须端到端地实现,以确保正确性。同时,端到端实现已足够,无需网络提供额外支持。由于仅靠端到端实现就已足够,增加网络功能只会引入额外不必要的复杂性(和成本),而无法帮助我们真正实现需求。

需要注意的是,端到端原则并非一个始终成立的证明或定理。它是一种指导原则和哲学论证,不同的设计者可能会对这一原则提出支持或反对的不同论点。这里有一个例子说明端到端原则并非严格的规则。尽管端到端原则主张仅在终端主机上实现可靠性,但我们仍然可以在网络中额外增加一些可靠性措施,作为端到端检查的补充。

Designing Resource Sharing

Sharing Resources: Statistical Multiplexing

互联网的资源(交换机和链路)当然是有限的,所以我们需要解决一个关键的设计问题:如何在不同的用户之间共享资源?

回忆一个概念:flow,是在两个 end hosts 之间进行交换的 packet flow,显然互联网需要支持许多并发的flow。

所谓 statistical multiplexing 统计复用,就是根据需求动态分配资源。

统计复用得以实现的前提是:在实践中,总需求的峰值远低于各峰值需求的总和。

对于许多分布,我们可以证明总需求的高峰实际上更接近平均需求的总和,这远低于高峰需求的总和。

在实践中,网络设计不会为所有流量同时达到峰值的最坏情况预留资源。相反,我们动态共享资源,并期望峰值不会同时出现。然而,峰值仍有可能出现,这时就会有延迟、丢包等情况。

Sharing Resources: Circuit Switching and Packet Switching

我们知道了可以使用统计复用技术,那么我们如何在实际中分配资源?

packet switching:

  • 利用 best-effort 的经典设计

  • 路由器独立查看每个packet,将其转发到更接近目的地的路由器

  • 不考虑所谓的flow(个人理解,flow是Transport Layer的概念,而我们知道由于end-to-end principle,路由器是不考虑传输层的)

  • 路由器之间不存在协调,不存在资源的分配。

circuit switching:

  • 是基于预留机制的设计
  • 在数据流开始时,用户需明确请求并预留所需带宽
  • 数据传输完成后,这些资源可被释放以供他人预留
  • flow开始时,end-host计算出一条路径,然后发出一系列预留请求
  • flow结束时,source host再向接收方发送一条拆除消息,释放容量
  • 为什么叫 circuit(电路) switching,是因为这一概念源于电话

电路交换和分组交换都体现了统计复用。主要区别在于我们分配资源的粒度。前者按flow分配,后者 best-effort。

Circuit Switching vs. Packet Switching Trade-offs

这里原文抛出了四个问题,此处精简一下:

对于网络向应用程序开发者提供的抽象(或 API)而言,这是一个好的设计吗?

Circuit-Switching 提供了更易于理解的抽象,比如结果更容易预测、ISP收费更方便。

该方法在大规模应用时是否高效?它是否充分利用了网络中的所有可用带宽,还是存在带宽浪费的情况?

如果发送方速率恒定,那么二者都能充分利用;如果速率不定,那么circuit-switching更好利用资源。

分组交换效率更高的另一个原因是:电路交换需要额外的时间来建立和拆除电路。对于非常短的流来说,这尤其低效。

每种方法在大规模故障下的处理能力如何?

packet-switching 更擅长处理故障,因为如果有路由器故障了,这是不影响的:我们只需要换一条路径就好了。但是这对于 circuit switching 而言,就很困难了。

大规模实施每种方法的复杂度如何

circuit-switching真正实施起来非常复杂,这里浅举几个难点:

  • 路由器如何知道预留成功?
  • 如果预留请求在途中丢失怎么办?
  • 如果请求已发送且所有路由器都同意,但返回途中的确认被丢弃怎么办?
  • 如果预留被拒绝怎么办?终端主机是否应该重试并请求更少?

造成困难的根本原因是互联网的分布式,导致了路由器很难追踪其他路由器的状态。

Circuit Switching vs. Packet Switching In Practice

概括:在现代互联网中,分组交换是默认采用的方式;电路交换的应用场景较为有限。

Links

本小节关心数据包如何通过链路进行传输。

三个关键指标:

  • bandwidth 带宽:单位时间内可以在链路上发送多少bits
  • propagation delay 传播延迟:$\frac{链路长度}{信息在链路里的传输速度}$
  • 带宽延迟积 BDP:$BD \times PD$

你可能会问 transmission delay 去哪了?事实上 $TD = \frac{数据量(in \ bits)}{带宽}$

Packet Delay

这个延迟是传输延迟和传播延迟的总和

Bandwidth and Propagation Delay Tradeoffs

举了一个例子,分析哪种链路更好,得到的结论是:

  • 带宽大、传播延迟长的链路适合大数据包
  • 带宽小、传播延迟短的链路适合小数据包

有两个数据包同时到达,但是我们只能发送一个,这叫做瞬时过载

为了应对瞬时过载,路由器可以维护一个 packet queue

当没有传入数据包时,交换机可以清空队列并发送所有已排队的包。

如果一次性传入大量数据包,队列也无法absorb这么大的流量的话,就会丢包。这一点在后续 Congestion Control Unit 会详细讲解。

现在需要回过头来更新数据包延迟的计算公式。如今,数据包延迟是传输延迟、传播延迟和排队延迟的总和。