Computer Networking Introduction
Sources:
- Computer Networking: A Top-Down Approach
计算机网络概览
什么是计算机网络?
计算机网络,顾名思义,就是由一群可以互相通信的计算机设备连接起来组成的网络(netword)。用离散数学的语言说,每个设备是一个节点(node),而设备之间的连接就是边(edge),整个网络是一个图(graph)。
- 网络:世界上有很多计算机网络,包括一个学校的校园网,一个企业的企业网,甚至我们在自己的家中也可以搭建网络。而世界上最大的网络就是因特网(Internet),也被叫做互联网。为了和互联网做区分,所有其他网络(校园网,企业网,…)都被叫做局域网,而因特网就是最大的局域网。
- 设备:设备可以分为两种,一种是普通用户使用的设备,也就是手机,电脑等等,称为终端设备(endpoint device),简称终端(endpoint)或者主机(host);另一种是作为中继把各个终端连接起来的设备,包括工作在链路层的交换机(switch)和网络层的路由器(router)(我们之后会介绍网络的协议栈)。
- 不过,通常我们说的中继设备就是路由器。这是因为交换机所工作在的链路层属于比较低层,大部分用户和工程师都不会关心它。
- 设备之间的通信可以是有线的(铜缆,光纤,所谓的“网线”,…),也可以是无线的(蓝牙,WIFI,蜂窝移动网络…),我们会在物理层详细讨论这个问题。
- 你可以想到,各个终端间理论上可以直接相互通信,不需要任何中继设备,这样形成的网络在图论中叫做 Mesh 拓扑网络。但这是不切实际的,因为世界上的终端数量很多,彼此在地理上相隔可能很远,我们不可能给每个终端都建立对所有其他 N 个终端的 N 个物理连接。
网络通信的协议
计算机网络中的通信需要遵循协议(protocol),就像出行需要遵守交通规则一样。只不过,在计算机网络中传递的是数据(比特串),因此网络协议本质上是对数据交换方式的规范。
不同实体之间需要遵循的这种“约定”,在不同领域有不同的名称。例如:在编程中称为接口(interface),在应用交互中称为 API,在法律中称为合同(contract),在文化中称为约定(convention)。本质上,它们表达的是同一件事:两个实体(无论是进程、个人还是组织)在进行通信或交互时需要遵守的规则。
网络协议通常由国际组织制定,并以标准文档的形式发布。目前常见的标准文档称为 Request for Comments(RFC)。
互联网的协议栈(五层模型)
计算机网络这一领域最具代表性的特征之一,是其具有一个清晰而简洁的分层协议模型。在计算机科学中,为了便于理解和实现复杂系统,通常会对问题进行抽象和分层处理。例如,开发 Flash 游戏的人无需关心浏览器的具体实现,编写 Java 程序的开发者也不必了解操作系统内核的细节,而操作系统工程师同样无需深入掌握底层半导体原理。
与计算机科学的其他领域类似,计算机网络中的抽象同样遵循“分层”的思想,并且通常按照与物理实现的距离由近及远进行划分。最底层是实际传输的电信号,这一层通常不被纳入计算机网络的讨论范围;网络所关心的最底层,是以电信号为载体的比特串。而在最顶层,则是各类应用之间的通信协议,例如 HTTP 等。
基于这种分层思想,我们在应用层(应用间的消息)与物理层(比特串)之间划分出多个层级。根据划分粒度的不同,形成了五层模型和七层模型两种常见的协议体系。由于各层之间具有自下而上的依赖关系,因此整体结构被形象地称为“协议栈(stack)”。本文将采用较为常见的五层模型进行讨论。
各层的主要职责如下:
| 层 | 解决的问题 |
|---|---|
| L5: Application / 应用层 | 应用需要什么通信语义? |
| L4: Transport / 传输层 | 如何实现进程到进程通信? |
| L3: Network / 网络层 | 如何把数据送到目标主机? |
| L2: Link / 数据链路层 | 如何在一条物理链路上传输? |
| L1: Physical / 物理层 | 如何传输比特? |
应用层(Application)
- 实体:应用进程(浏览器、服务器、客户端程序)
- 协议:HTTP、DNS、SMTP、FTP
- 设备:主机(不涉及专用网络设备)
- 作用:定义应用之间的数据格式与语义
传输层(Transport)
- 实体:主机中的传输层协议栈(操作系统内核)
- 协议:TCP、UDP
- 设备:主机
- 作用:提供进程到进程的通信
网络层(Network)
- 实体:主机 + 路由器
- 协议:IP(以及路由协议如 OSPF、BGP)
- 设备:路由器(Router)
- 作用:主机到主机的转发与路径选择
链路层(Link)
- 实体:网络接口(NIC)
- 协议:Ethernet、WiFi(802.11)
- 设备:交换机(Switch)、网卡
- 作用:相邻节点之间的数据传输
物理层(Physical)
- 实体:物理接口(电路/光模块)
- 协议:比特编码规则(如电压、调制方式)
- 设备:网线、光纤、无线信道
- 作用:比特在介质上的实际传输
协议数据单元(PDU)
各网络协议层中所使用的数据单位统称为协议数据单元(Protocol Data Unit,PDU)。在不同的协议层中,PDU 具有不同的具体名称:
| 层次 | 常见 PDU 名称 |
|---|---|
| 应用层 | message / 报文 |
| 传输层 | TCP:segment / 段;UDP:datagram / 数据报 |
| 网络层 IP | packet 包 |
| 数据链路层 | frame / 帧 |
| 物理层 | bit / 比特 |
PDU 遵循如下结构:一个头部(header)用于存储控制信息,比如协议名字,目的 ip 地址等等;一个载荷(payload)以存储真正要传输的数据内容;有些 PDU 还会附加一个尾部(trailer)用于数据校验等目的。
1 | PDU = header + payload (+ 可选 trailer) |
例如:
1 | TCP segment = TCP header + data |
PDU 的封装
1. 封装思想
在分层结构中,每一层只处理属于自己的信息。也就是说:
- 传输层只关心 TCP segment
- 网络层只关心 IP packet(datagram)
- 链路层只关心 frame
但与此同时,上层的数据必须被包含进下层,并最终包含进物理层(否则就没有没有物理介质,也就没法通信)。因此,各层之间的数据关系是:
1 | Application Message |
也就是:
- segment 被放入 packet 中
- packet 被放入 frame 中
这个包含操作有一个术语,叫做“封装(encapsulation)”。
2. 封装的实现方式
由于 PDU 都是 header + payload 的结构,因此封装的最自然的实现方式就是 把上层 PDU 作为下层的 payload,再加上当前层的 header:
1 | 上层 PDU(payload) |
具体来说,每一层只做两件事:
- 处理自己的信息(如端口号、IP 地址、MAC 地址等)
- 把上层数据整体当作 payload 包含进去
(可能还会附带一些操作,例如校验、加密等)
3. 示例:一次 HTTP 请求在协议栈中的封装过程
一个简单的例子是:当我通过应用层的 HTTP 协议访问网站 example.com 时,会生成一个应用层报文(message):
1 | +----------------------------------------------+----------------------+ |
3.1. 传输层(TCP)
这个报文会作为 payload 被 TCP 封装,形成一个 segment:
1 | +------------------+----------------------------------------------+ |
3.2. 网络层(IP)
接着,TCP segment 会作为 payload 被 IP 封装,形成一个 packet:
1 | +------------------+----------------------------------------------+ |
3.3. 链路层
IP packet 在链路层会被进一步封装为 frame:
1 | +------------------+----------------------------------------------+ |
3.4. 物理层
最终,在物理层中,这些 frame 会被转换为:
1 | 010101010101010101010101... |
即在链路上传输的比特流(电信号)。
4. 数据分片
虽然在逻辑上一个高层 PDU 会被作为 payload 完整地封装进一个低层 PDU,例如:
1 | Application Message |
但是,为了避免一个PDU 长时间占用链路,同时为了允许多个 PDU 共享一个链路,我们在实现上会把数据进行切分。切分可以发生在传输层,IP 层和链路层:
1 | 原始 Message |
例如:
1 | 一个 Message 被切成两段: |
然后:
1 | Segment1 = [TCP H | M1] |
再继续封装:
1 | Packet1 = [IP H | Segment1] |
因此,封装是逻辑层面的,而在实现中上可能会切片。
通信方式:分组交换
每个数据包在网络层中被独立地转发:
1 | 主机 → 路由器 → 路由器 → … → 主机 |
路由器对经过它的每一个数据包执行:
- 接收一个完整数据包
- 查转发表(根据包中含有的目的地址)
- 从某个接口发出去
这里有两个注意点:
- 每个数据包可能走不同路径
- 数据包必须在当前路由器完整接收后,才会被转发。这和视频直播等领域中的流式传输不同。
- 整个路径不是一次完成的,而是一跳(hop)一跳地推进,因此也被称为逐跳转发(store-and-forward)
附录
网络领域常见的性能指标
吞吐量
throughput: 单位时间内通过某个网络的实际的数据量时延
latenty:数据从网络的一端传送到另一端的时间- 发送时延:主机或
router发送数据帧所需要的时间- = 数据帧长度 / 发送速率
- 传播时延:电磁波在信道中传播一定的距离需要花费的时间
- = 心道长度 / 电磁波在信道中的传播速率
- 处理时延:主机或
router处理收到的分组的时间 - 排队时延:分组在
router的输入队列中排队等待处理- 丢包:分组如果到达一个满的队列,
router将drop该分组
- 丢包:分组如果到达一个满的队列,
- 总时延 = 发送时延 + 传播时延 + 处理时间 + 排队时延
- 我们一般只能提高发送时延, “光线比铜线快”指的是可以用很快的速率向光纤信道发送数据,光纤信道上的传播速率实际上比铜线慢
- 发送时延:主机或
往返时间
RTT(Round-Trip Time)