网站空间商是什么,国外二级域名免费申请,嵌入式软件开发笔试题目,外语人才网知乎的一个问题很有意思#xff1a;“为什么在TCP首部中要把TCP的端口号放入最开始的四个字节#xff1f;”
这种问题很适合我这种搞历史的人#xff0c;大年初一我给出了一个简短的解释#xff0c;但仔细探究这个问题#xff0c;我们将会获得 TCP/IP 被定义的过程。
文…知乎的一个问题很有意思“为什么在TCP首部中要把TCP的端口号放入最开始的四个字节”
这种问题很适合我这种搞历史的人大年初一我给出了一个简短的解释但仔细探究这个问题我们将会获得 TCP/IP 被定义的过程。
文顿瑟夫(Vinton Cerf)和罗伯特卡恩(Robert Kahn)的《A Protocol for Packet Network Intercommunication》看似是一个开端但在当时(1970 年代初)它只是在罗列 NCP 的问题并给出的一个解决方案事后看这个解决方案就是 TCP/IP。这是典型的从一个方案中诞生的一个新东西。 有此论文作为理论基础定义和实现在 RFC675 中被展示。问题 “为什么在TCP首部中要把TCP的端口号放入最开始的四个字节” 也能在其中找到答案。
看一下 RFC675 第 4.2.1 节就够了最初(1974 年)的 TCP 和 IP 是合在一起的就叫 TCP最初的 TCP port 字段放在最后面(仅在校验码之前24 bit)而不是最前面。但 675 定义的 TCP 合理吗
50 年过去了从现在的视角看 50 年前 TCP 的设计可以获得很多启发Judith Estrin 分享了从文顿瑟夫和罗伯特卡恩那里学到的原则其中一个是为不确定性做计划协议不能假设来自下层或上层的任何东西另一个相关的原则是互连多样性以获得集体力量而不是同质化扩展。
这意味着 “数据流”“可靠”“保序” 的假设应该被去除同时应该为 “互连多样性” 抽取一个最小公共集这样一来 675 就变形了
当 UDP 不得不被抽象出来之后独立出来的 IP 必须单独分离分离的过程其实是一个非常常规的过程TCP675 把将要属于最小公共集 IP 的字段一个个往前挪到独立的 IP 头是最自然的做法。这个过程一直持续到最后端口字段由于 UDP 也需要它来解复用这两个字段本不属于 IP自然不能往前挪但由于当时只有 TCP 和 UDP 两个协议且 TCP 和 UDP 都需要端口就判断它虽不属于最小公共集但属于独立解复用的 “子层”这样它们就紧挨着 IP 的最后处在 IP 和 TCP/UDP 之间所以还是挪了这就造成了如今 TCPUDP 协议头的格局端口处在最前面的 4 个字节。
这样的协议头带来一个非常好的正向副作用当路由器交换机这些转发节点需要进行包分类时可以快速定位端口号从而高效识别五元组这在侧面催生并加强了防火墙NAT 等 mid-box 向高性能方向发展。
另一方面 ICMP隧道封装协议路由控制协议这类控制协议并非端应用或服务并不需要端口来解复用它们多属于 TCP/IP 协议族的控制平面也就自然而然与 TCPUDP 并列了通过 IP 协议的 protocol 字段来识别解复用。
但总有人玩花活儿看不上 TCP又不基于 UDP 之上构建却在 134254 间新开辟一个独立的协议号以示创新。设计这个新协议的初衷是嫌 16-bit 端口号不够用想使用 24-bit 端口号。但这真的需要开辟一个新协议号吗
TCP/IP 的灵活性和可扩展性简直炸天但凡想对 TCP/IP 大动筋骨的思路很大概率都是错的甚至不需要微创它本身的扩展性就足以满足几乎任何需求。事实上是玩花活儿的人误解了做事的目标目标不是解决端口不够用的问题而是解决复用度的问题要么参考我此前的端口不均衡的思路要么就让 UDP 仅作为一个负载均衡层在 UDP 之上构建 24-bit 端口号的新协议。
很多改造 TCP 的想法都可在 UDP 上实现首先我在 UDP 上照抄一份 TCP 代码UDP 仍只做负载均衡层然后修改这些 TCP 代码比如把端口号改成 24-bit支持 NACK修改 RTO 机制修改 SACK 机制使用保留 bit 等等。
回到文初的问题现在可以一句话回答了“为什么在TCP首部中要把TCP的端口号放入最开始的四个字节”因为 “TCP/IP 最初的诞生过程中偶然在 TCP|UDP 和 IP 之间引入了一个 ‘解复用子层’这个子层就是目标端口和源端口”。
如果说 TCP/IP 的缺陷和其它任何现代工业设施一样确实是 “低估了数字”8-bit 网络号被 32-bit IP 地址替换但还是不够16-bit 端口号虽可基于 UDP 加层扩展但很麻烦这就像停车位永远不够固定电话频繁升位一样一开始人们总觉得足够大但很快就不够用。
浙江温州皮鞋湿下雨进水不会胖。