1.A day in the life of an application - Katyusha's blog
mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7
1156 字
3 分钟
1.A day in the life of an application
2026-08-27

从可靠字节流到 P2P 通信#

共同的基础:双向可靠字节流#

网络应用虽然用途不同,但都可以建立在同一种抽象上:两台机器上的程序之间有一条双向、可靠的字节流。一端按顺序写入字节,另一端按顺序读出字节;应用只需要规定这些字节代表什么。

HTTP:客户端向固定服务器要文档#

Web 的常见模式是客户端—服务器:浏览器向一个公开可访问的服务器发请求,例如 GET /index.html;服务器返回内容和状态码,例如 200404502

HTTP 请求和响应示例是人能直接读懂的文本,图片、视频等响应体可以是二进制数据,现代 HTTP/2、HTTP/3 的底层帧也不是纯文本。

BitTorrent:许多客户端共同分发一个文件#

BitTorrent 中没有唯一的数据服务器。拥有同一文件的客户端下载、上传,构成一个 swarm(集群)。文件被分成许多 pieces(片段),所以一个客户端可以同时向多个 peer 请求不同片段,下载完后也把已有片段分享给别人。

下载前,客户端会从 .torrent 文件获得文件的描述和 tracker 信息。tracker 的主要工作是发现:告诉客户端“有哪些 peer 可能拥有这个文件”;数据本身通常仍在 peer 之间传输。

A 向 tracker 查询文件 X
tracker 返回一批候选 peer
A 尝试连接其中可达的 peer,并交换 pieces

所以 BitTorrent 也需要某种“找人”的机制(tracker、DHT 等),并不是天然不受 NAT 影响。只是它通常不执着于连接某一个特定用户:某个 peer 连不上时,可以换另一个有相同片段的 peer。

NAT:为什么个人设备不容易被主动连接#

家庭路由器或移动网络常使用 NAT(网络地址转换)。家里的多台设备可以共享同一个公网 IP;路由器用端口和一张临时映射表区分不同设备。

电脑 A1: 192.168.1.10:50000 ──> 公网 203.0.113.7:40001
电脑 A2: 192.168.1.11:50000 ──> 公网 203.0.113.7:40002

当 A1 主动访问外部服务器时,NAT 建立映射。服务器随后发回 203.0.113.7:40001 的数据,NAT 就能交给 A1。

问题在于外部机器若想新建一条到 A1 的连接,NAT 往往没有对应的映射,不知道该把数据交给哪台内网设备,于是通常丢弃。简化地说:NAT 后的设备容易主动出站,外部却不容易主动入站。

Skype:需要找到并通知“特定的 B”#

课程中的 Skype 例子是历史教学模型。A 想呼叫的是指定用户 B;若 B 在 NAT 后,A 直接连 B 可能失败。此时需要公网的 rendezvous(会合)服务器 R。

关键点是:B 登录时先主动连到 R,并保持一条控制连接。A 发起呼叫后,R 不会从外部新开一条连接闯进 B;它只是沿 B 已经建立的连接,把“有人呼叫你”的消息写回给 B。

B ──先主动连接──> R
A ──“我要呼叫 B”──> R
R ──沿 B 的既有连接通知──> B

这条连接能穿过 NAT,是因为 B 出站时已建立映射;R 发回的是这条既有连接的返回流量。实际系统会保持连接或定期发送 keepalive,避免映射因空闲过期。

收到通知后:

  • 若 A 可被访问,B 可以主动连接 A。这叫反向连接:呼叫意图来自 A,但建连动作由 B 发起;连上后数据仍可双向传输。
  • 若 A、B 都在 NAT 后且无法打洞或端口映射,则双方分别主动连接公网 relay(中继)服务器,由中继转发语音、视频或聊天数据。
A ──> relay ──> B
B ──> relay ──> A

会合服务器主要传递“谁在找谁、是否接听”等控制消息,开销较小;relay 位于实际数据路径上,需要转发媒体流量,因此是直连失败时的保底方案。

三者的区别#

应用主要问题辅助角色数据通常怎么走
HTTP向固定服务器请求资源服务器客户端 ↔ 服务器
BitTorrent找到任意拥有片段的 peertracker / DHTpeer ↔ peer
Skype通知并连接指定的用户rendezvous;失败时 relay优先直连,失败时经 relay
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

1.A day in the life of an application
https://katyusha-blog.com/posts/cs144/notes/1a-day-in-the-life-of-an-application/
作者
katyusha
发布于
2026-08-27
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录