第95期 | 一个文件描述符,怎么装下整张网?

操作系统 · · 九羲科技

第12章第一期。上一章讲完中断怎么听门铃,这一章换一张网卡:网络协议栈。从 BSD socket 到千万并发,第一期先问 socket 是从哪来的。

一、1983 年,整张网缩进一个整数:

1983 年 8 月,4.2BSD 发布,随之问世的是 socket API——程序员从此用一个整数(文件描述符)代表远方的一台机器²。往前倒九年,1974 年 Cerf 和 Kahn 的论文已经把"不同的网络怎么连成一张网"写全了¹;socket 是这条路上的应用层答案。

最反常识的细节藏在分工里:DARPA 当年并不放心让伯克利的学生写网络协议,真正的 TCP/IP 协议栈是雇 BBN 写的,Bill Joy 只负责写 API,也就是今天 socket()、bind()、listen()、accept() 这一套³。Joy 等不及 BBN 的成品,先拿了个原型回来测 API,结果 BBN 的代码是在 50kbit 的 ARPANET 骨干上调出来的,伯克利手里却是 Xerox PARC 的 3Mbit 实验网——快了 60 倍,代码根本吃不满。Joy 的反应很 Joy:亲自动手重写了 BBN 的部分代码。后来 BBN 把正式版写完送过来,Joy 拒收了:我们已经有能跑的了³。DARPA 把两边都测了一遍,判定伯克利的版本更优,留了下来。

socket 最狠的一笔,是把它塞进了 Unix 的文件描述符体系:一张网卡、一段连接,和打开的文件一样,都是一个整数,都能 read、write、close²。这不是技术细节,是世界观:网络从此是"一切皆文件"的延伸。而这一切的前提,是半年前的 1983 年 1 月 1 日,ARPANET 全网切换 TCP/IP⁶——先有统一的路,才有统一的门牌。

socket 的前世:1969 年 ARPANET 通车 → 1974 年 Cerf/Kahn 论文(TCP 原型)→ 1983 年全网切换 TCP/IP → 1983 年 8 月 4.2BSD 发布、socket API 问世 → 1989 年网络代码摆脱 AT&T 许可 → socket 成为 POSIX 事实标准,沿用至今。

二、AI 的连接,不该再是字节流:

如果 AI 的操作系统先出现,它大概不会发明 socket。socket 传的是字节流,可智能体之间要传的是意图、上下文和任务状态——旧抽象装新负载,迟早漏。

最新的进展把这话说透了。2026 年 10 月 26 日,Jack Klimov 发表《A2A Is for Strangers》⁴:A2A 协议把每个对外暴露的智能体变成一个网络服务——一张 agent card、一个端点,长交互还要一个任务存储。他的判断很锋利:这套东西在"陌生人"之间(另一个部门、供应商、别的平台)划算,在自己的紧密舰队里多半是 overhead。他引了 Eon 的一句话:"你没法导入一个陌生人的智能体,你只能调用它。"⁴

推演一步:在原生 AI OS 里,"连接"的最小单位不是 socket 那样的字节管道,而是一条"意图通道"——握手时交换的不是 IP 加端口,而是能力卡(我能做什么)、上下文指针(我记得什么)、任务状态机(做到哪一步)。DZone 10 月 27 日的 A2A 治理教程⁵,恰好画出了这条通道的三段:Agent Card 上写明哪些能力要审批(发现时就看见代价)、AGENTS.md 里写死三类操作(规则可审)、状态机里留出 input-required 这一态(审批是流程里的一站,不是事后补票)。这就是 AI 时代的"三次握手":能力发现、治理校验、任务委派。

言外之物在这里:socket 的魔法,是把"远"伪装成"近"——一个本地整数,背后是一整张网。而 AI 时代最容易犯的错正好反过来:把"近"伪装成"远"。自家智能体之间本来就能共享上下文、共享状态,非要先拆成陌生人,再走一遍契约、任务存储、版本协调的谈判——每一次跨服务调用都在交税。协议正热的时候,拿对外协议管对内协作,是最贵的一种时髦。

三、数一数,你机器上有多少扇门:

今晚就能动手,不用装任何东西。先看全景:ss -s,一行行数出来——TCP、UDP、RAW 各建了多少 socket,多少处于 TIME_WAIT。ss 的输出,就是 socket 的人口普查。

再看明细:cat /proc/net/tcp。每一行就是一个连接:本地地址、远端地址都是十六进制的 IP:端口,st 字段是状态——01 是 ESTABLISHED,0A 是 LISTEN。亲手把 0A 翻成十进制的那一刻,"监听"就从抽象变成了表格里的一行。

然后做个小实验:写两个 20 行的 Python echo server,一个来一个连接就 fork 一个子进程,一个单进程死守 select 循环。用 wrk 或 ab 压 1000 个并发,看 CPU 和延迟的差距——C10K 问题二十年前问的,就是这一道题。

这套手感可以直接搬去量 SkyBook 私有智能中心里智能体之间的调用:跨组织边界的走 A2A 协议(陌生人),同一舰队内部的走共享上下文直调(自家人)。Klimov 的判断就是这把尺子:先数清哪些是"远"、哪些是"近",再决定要不要交那份协议税。

觉 然 小 注

socket 把远方折成一个整数揣进口袋,这是 1983 年的温柔。而下一个四十年要学的,也许是把整数重新展开——认出哪些连接本是自家人,不必再走一遍握手的客套。凡发生必有利于我:省下的每一次握手,都是多留一分算力,给真正要想的事。

引 用 与 出 处

  1. [1] Vinton G. Cerf, Robert E. Kahn. A Protocol for Packet Network Intercommunication. IEEE Transactions on Communications, 1974. DOI: 10.1109/TCOM.1974.1092259
  2. [2] Berkeley sockets. Wikipedia 词条. https://en.wikipedia.org/wiki/Berkeley_socket
  3. [3] Klara Systems. History of FreeBSD – Part 4: BSD and TCP/IP. https://klarasystems.com/articles/history-of-freebsd-part-4-bsd-and-tcp-ip/?amp(二手梳理,转引;博客成色)
  4. [4] Jack Klimov. A2A Is for Strangers. 作者博客,2026-10-26. https://jack.direct/blog/when-to-use-a2a/
  5. [5] DZone. Quarkus A2A Agent Governance(系列第 4 篇). DZone 教程,2026-10-27. https://dzone.com/articles/quarkus-a2a-agent-governance(公开教程实现,非生产系统)
  6. [6] ARPANET. Wikipedia 词条. https://en.wikipedia.org/wiki/ARPANET

· · ·

← 返回资讯中心