协议和系统设计背后那些"为什么这样而不那样"。
不是为了"确认双方都能收发"那么简单。RFC 793 Section 3.4的真正原因:防止历史重复连接请求(old duplicate)被错误接受。
两次握手的话,一个延迟到达的旧SYN会让服务端以为是新连接,单方面打开,浪费资源。第三次ACK让客户端有机会说"这个SYN不是我发的"。
本质上是在不可靠的网络上用最少的往返确认双方的初始序列号。
RFC 793 §3.4
第一位表示分类(1xx信息/2xx成功/3xx重定向/4xx客户端错误/5xx服务端错误),后两位表示具体情况。三位数给了100个编号空间每类,够用但不浪费。
404从"文件未找到"变成了文化符号——"不存在/被删除/被审查"的代名词。橙橙的404页面写的是"它在。只是你猜错了地址。"
Mike Muuss 1983年写的,名字来自声呐的声音。发一个信号出去,听回声,测距离。ICMP echo request/reply就是网络版的声呐。
Muuss说"I named it after the sound that a sonar makes." 37个字的程序,用了四十多年。
Ken Thompson和Rob Pike 1992年在新泽西一家餐厅的餐垫纸上设计的。核心约束:向后兼容ASCII(高位0=1字节=ASCII),同时能编码所有Unicode码位(最多4字节)。
代价是解析复杂,收益是英文文本跟ASCII一样大。固定4字节(UTF-32)太浪费,UTF-16对中文友好但不兼容ASCII。UTF-8两全其美但丑。
查询+响应通常一个包就装得下(512字节以内)。TCP三次握手的开销对"问一个域名对应什么IP"这种事太重了——等你握完手别人都解析完了。
但超过512字节的响应(比如DNSSEC签名)会退回TCP。所以DNS不是"只用UDP",是"默认UDP,装不下了换TCP"。
TCP/UDP头部里端口字段是16位。2^16=65536,从0数到65535。不是拍脑袋定的,是当年觉得"6万5千个够用了"。
0-1023是well-known ports(HTTP 80、HTTPS 443、SSH 22),1024-49151是registered,49152-65535是ephemeral(临时端口,系统随机分的)。
127是Class A的最后一个网段,被留作回环。发给127.x.x.x的包不出网卡,直接回到本机。实际只用127.0.0.1,但整个/8(1600万个地址)都保留了。
真正有意思的不是"为什么是127",而是"为什么觉得浪费1600万个地址无所谓"。1981年RFC 791设计IPv4的时候,互联网只有几百台主机,42亿个地址是天文数字。设计者的假设——"地址永远够用"——被现实推翻了。
这本身就是意义漂移:一个基于"地址无限"假设做的设计决定,在地址枯竭的现实里变成了浪费。但改不了了,因为127.0.0.1已经硬编码进了无数系统。