跳轉到

1983 - BSD 4.2 的 TCP/IP 與 Socket(網路化作業系統)#

案件摘要#

1983 年 8 月,UC Berkeley 發布 4.2BSD——第一個內建 TCP/IP 網路協定的作業系統。 Bill Joy 與 Sam Leffler 設計的 Socket API(插座介面),讓「網路連線」變成「讀寫檔案」——

\[ \text{socket} \;\approx\; \text{open / read / write / close} \quad \text{——網路即檔案的第二次統一}. \]

Unix 從單機作業系統變成網路作業系統——今天的網際網路,一半建立在這個案子之上。

前因 -- 為什麼會有這個案子#

  • DARPA 的需求:1980 年代美國國防部要把 ARPANET 全面遷移到 TCP/IP,需要一個能跑 TCP/IP 的通用系統——Berkeley 的 Unix 被選中,DARPA 出錢,Berkeley 出工。
  • VAX 叢集的需求:Berkeley 買了多台 VAX,機器之間要通訊、共用檔案——單機 OS 已不夠用。
  • 彌補的缺陷:當時網路程式設計五花八門(每種網路一套專用 API)——4.2BSD 用 socket 統一所有網路的介面。

線索與推理 -- 數學式、程式、理論#

第一條線索:Socket——一切皆檔案的延伸#

\[ \text{本地檔案:open → read → write → close} \]
\[ \text{網路連線:socket → connect → read → write → close} \]
  • 彌補的缺陷:若網路用專用 API(如當時的 DECnet),每種協定都要重學。socket 把「位址+協定」抽象成「檔案描述子」——理論上是把 I/O 統一抽象再推進一步。
  • 四元組模型:一條 TCP 連線 = (本地位址, 本地埠, 遠地位址, 遠地埠)——數學上就是一個有序四元組。

第二條線索:TCP/IP 協定堆疊#

\[ \text{應用層} \subset \text{TCP/UDP(傳輸層)} \subset \text{IP(網路層)} \subset \text{乙太網路(鏈路層)}. \]

Berkeley 實作完整協定堆疊於核心——層次化解耦:應用只需面對 socket,不需懂 IP 細節。

第三條線索:r 系列工具與 DNS#

4.2BSD 附帶 rlogin、rsh、rcp(遠端作業工具)與 BIND/DNS 的前身——網路工具鏈第一次成為 OS 標配。

C 範例:Socket 網路程式(echo server)#

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>

int main(void) {
    int s = socket(AF_INET, SOCK_STREAM, 0);   /* 1. socket */
    struct sockaddr_in addr = {0};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(7);
    bind(s, (struct sockaddr *)&addr, sizeof(addr));  /* 2. bind */
    listen(s, 5);                                     /* 3. listen */
    for (;;) {
        int c = accept(s, NULL, NULL);                /* 4. accept */
        char buf[256];
        int n = read(c, buf, sizeof(buf));            /* 5. read */
        write(c, buf, n);                             /* 6. echo */
        close(c);                                     /* 7. close */
    }
}
(與讀檔案同一組系統呼叫——socket = 網路檔案。)

Shell 範例:4.2BSD 遺產的日常使用#

$ ssh server.example.com     # rlogin 的加密後裔
$ scp file.txt server:~/     # rcp 的後裔
$ curl https://example.com   # socket API 的現代應用
$ dig example.com            # BIND/DNS 的直系後裔

Python 範例:socket 的現代寫法#

import socket

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect(("example.com", 80))
    s.sendall(b"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n")
    print(s.recv(4096).decode()[:200])

結案 -- 後果與影響#

  • 網際網路的 OS 基礎:1983–94 年,大學與研究機構的網路幾乎全是 BSD Unix——TCP/IP 因 4.2BSD 而普及。
  • Socket API 成為事實標準:進入 POSIX(1988),今天所有語言(C、Python、Go、Rust)的網路程式設計都是 socket 的後裔。
  • Sun Microsystems(1982):Bill Joy 離開 Berkeley 創辦 Sun,把 BSD 商業化為 SunOS + NFS(1984)——工作站時代開啟。
  • BSD 的授權之爭:1989 年 Berkeley 提出 BSD 授權(幾乎無限制)——與 GNU GPL 分庭抗禮的自由軟體授權。
  • 歷史教訓:統一介面(socket)比統一實作(協定)更影響深遠。

關鍵人物與文獻#

  • B. Joy, S. Leffler, M. McKusick:4.2BSD TCP/IP 與 socket。
  • L. Seiferas / DARPA:TCP/IP 標準化(1981 RFC 793)。
  • 相關案件:1975-Version6與BSD起源.md、1989-POSIX標準與BSD授權.md。