当前位置: 首页 > news >正文

TCP 端口号为何位于首部前四个字节?协议设计的智慧与启示

知乎的一个问题很有意思:“为什么在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 之间,所以还是挪了,这就造成了如今 TCP,UDP 协议头的格局,端口处在最前面的 4 个字节。

这样的协议头带来一个非常好的正向副作用,当路由器交换机这些转发节点需要进行包分类时,可以快速定位端口号,从而高效识别五元组,这在侧面催生并加强了防火墙,NAT 等 mid-box 向高性能方向发展。

另一方面, ICMP,隧道封装协议,路由控制协议,这类控制协议并非端应用或服务,并不需要端口来解复用,它们多属于 TCP/IP 协议族的控制平面,也就自然而然与 TCP,UDP 并列了,通过 IP 协议的 protocol 字段来识别解复用。

但总有人玩花活儿,看不上 TCP,又不基于 UDP 之上构建,却在 134~254 间新开辟一个独立的协议号,以示创新。设计这个新协议的初衷是嫌 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 加层扩展,但很麻烦,这就像停车位永远不够,固定电话频繁升位一样,一开始人们总觉得足够大,但很快就不够用。

浙江温州皮鞋湿,下雨进水不会胖。

相关文章:

TCP 端口号为何位于首部前四个字节?协议设计的智慧与启示

知乎的一个问题很有意思:“为什么在TCP首部中要把TCP的端口号放入最开始的四个字节?” 这种问题很适合我这种搞历史的人,大年初一我给出了一个简短的解释,但仔细探究这个问题,我们将会获得 TCP/IP 被定义的过程。 文…...

HTML之JavaScript函数声明

HTML之JavaScript函数声明 1. function 函数名(){}2. var 函数名 function(){}<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1…...

R 数组:高效数据处理的基础

R 数组&#xff1a;高效数据处理的基础 引言 在数据科学和统计分析领域&#xff0c;R 语言以其强大的数据处理和分析能力而备受推崇。R 数组是 R 语言中用于存储和操作数据的基本数据结构。本文将详细介绍 R 数组的创建、操作和优化&#xff0c;帮助读者掌握 R 数组的使用技巧…...

git服务器搭建,gitea服务搭建,使用systemclt管理服务

文章目录 页面展示使用二进制文件安装git服务下载选择架构使用wget下载安装 验证 GPG 签名服务器设置准备环境创建systemctl文件 备份与恢复备份命令 (dump)恢复命令 (restore) 页面展示 使用二进制文件安装git服务 所有打包的二进制程序均包含 SQLite&#xff0c;MySQL 和 Po…...

Pdf手册阅读(1)--数字签名篇

原文阅读摘要 PDF支持的数字签名&#xff0c; 不仅仅是公私钥签名&#xff0c;还可以是指纹、手写、虹膜等生物识别签名。PDF签名的计算方式&#xff0c;可以基于字节范围进行计算&#xff0c;也可以基于Pdf 对象&#xff08;pdf object&#xff09;进行计算。 PDF文件可能包…...

嵌入式WebRTC压缩至670K,目标将so动态库压缩至500K,.a静态库还可以更小

最近把EasyRTC的效果发布出去给各大IPC厂商体验了一下&#xff0c;直接就用EasyRTC与各个厂商的负责人进行的通话&#xff0c;在通话中&#xff0c;用户就反馈效果确实不错&#xff01; 这两天有用户要在海思hi3516cv610上使用EasyRTC&#xff0c;工具链是&#xff1a;gcc-2024…...

百度高德地图坐标转换

百度地图和高德地图的侧重点不太一样。同样一个地名&#xff0c;在百度地图网站上搜索到的地点可能是商业网点&#xff0c;在高德地图网站上搜索到的地点可能是自然行政地点。 高德地图api 在高德地图中&#xff0c;搜索地名&#xff0c;如“乱石头川”&#xff0c;该地名会出…...

ES 索引结构

ES 既不像 MySQL 这样有严格的 Schema&#xff0c;也不像 MongoDB 那样完全无 Schema&#xff0c;而是介于两者之间。 1️⃣ ES 的 Schema 模式 ES 默认是 Schema-less&#xff08;无模式&#xff09; 的&#xff0c;允许动态添加字段。 但 ES 也支持 Schema&#xff08;映射 …...

HPM_SDK应用本地化——基于6750evkmini

文章目录 前言一、准备工作1、下载官方的SDK2、解压SDK 二、实操1、新建目标工程文件夹2、回到SDK中将相关文件复制1、Borad文件夹2、hello_world文件夹 三、实验现象总结 前言 为什么要对sdk进行应用本地化&#xff1f;在嵌入式开发中我们一般将官方提供的SDK作为参考&#x…...

【deepseek-r1本地部署】

首先需要安装ollama,之前已经安装过了&#xff0c;这里不展示细节 在cmd中输入官网安装命令&#xff1a;ollama run deepseek-r1:32b&#xff0c;开始下载 出现success后&#xff0c;下载完成 接下来就可以使用了&#xff0c;不过是用cmd来运行使用 可以安装UI可视化界面&a…...

查询语句来提取 detail 字段中包含 xxx 的 URL 里的 commodity/ 后面的数字串

您可以使用以下 SQL 查询语句来提取 detail 字段中包含 oss.kxlist.com 的 URL 里的 commodity/ 后面的数字串&#xff1a; <p><img style"max-width:100%;" src"https://oss.kxlist.com//8a989a0c55e4a7900155e7fd7971000b/commodity/20170925/20170…...

堆排序

目录 堆排序&#xff08;不稳定&#xff09;&#xff1a; 代码实现&#xff1a; 思路分析&#xff1a; 总结&#xff1a; 堆排序&#xff08;不稳定&#xff09;&#xff1a; 如果想要一段数据从小到大进行排序&#xff0c;则要先建立大根堆&#xff0c;因为这样每次堆顶上都能…...

【MySQL】我在广州学Mysql 系列—— 数据备份与还原

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天周一&#xff0c;过两天就是元宵节了&#xff0c;今年元宵节各位又要怎么过呢&#xff01;&#xff01; 本文主要对Mysql数据库中的数据备份与还原内容进行讨论&#xff01;&#xff01; 回顾&#xff1a;&#x1f449;【MySQ…...

【LeetCode Hot100 双指针】移动零、盛最多水的容器、三数之和、接雨水

双指针 1. 移动零题目描述解题思路关键思路&#xff1a;步骤&#xff1a;时间复杂度&#xff1a;空间复杂度&#xff1a; 代码实现 2. 盛最多水的容器题目解析解题思路代码实现 3. 三数之和问题描述&#xff1a;解题思路&#xff1a;算法步骤&#xff1a;代码实现&#xff1a; …...

HTML应用指南:利用POST请求获取接入比亚迪业态的充电桩位置信息

在新能源汽车快速发展的今天,充电桩的分布和可用性成为了影响用户体验的关键因素之一。比亚迪作为全球领先的新能源汽车制造商,不仅在车辆制造方面取得了卓越成就,也在充电基础设施建设上投入了大量资源。为了帮助用户更方便地找到比亚迪充电桩的位置,本篇文章,我们将探究…...

Android车机DIY开发之软件篇(十二) AOSP12下载编译

Android车机DIY开发之软件篇(十二) AOSP12下载编译 sudo apt-get update sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib gmultilib libc6-dev-i386 lib32ncurses5-dev libx11-dev lib32z-dev ccache libgl1-mesa-…...

Jenkins+gitee 搭建自动化部署

Jenkinsgitee 搭建自动化部署 环境说明&#xff1a; 软件版本备注CentOS8.5.2111JDK1.8.0_211Maven3.8.8git2.27.0Jenkins2.319最好选稳定版本&#xff0c;不然安装插件有点麻烦 一、安装Jenkins程序 1、到官网下载相应的版本war或者直接使用yum安装 Jenkins官网下载 直接…...

【文本处理】如何在批量WORD和txt文本提取手机号码,固话号码,提取邮箱,删除中文,删除英文,提取车牌号等等一些文本提取固定格式的操作,基于WPF的解决方案

企业的应用场景 数据清洗&#xff1a;在进行数据导入或分析之前&#xff0c;往往需要对大量文本数据进行预处理&#xff0c;比如去除文本中的无关字符&#xff08;中文、英文&#xff09;&#xff0c;只保留需要的联系信息&#xff08;手机号码、固话号码、邮箱&#xff09;。…...

Linux系统引导与服务管理

目录 一、Linux引导过程 1、引导过程概述 1.1、BIOS开机自检 1.2、MBR读取 1.3、加载引导加载程序&#xff08;GRUB&#xff09; 1.4、内核加载 1.5、初始化进程&#xff08;init&#xff09; 二、服务 2.1、服务类型 2.2、服务管理工具 三、运行级别 四、systemd …...

网络工程师 (30)以太网技术

一、起源与发展 以太网技术起源于20世纪70年代&#xff0c;最初由Xerox公司的帕洛阿尔托研究中心&#xff08;PARC&#xff09;开发。最初的以太网采用同轴电缆作为传输介质&#xff0c;数据传输速率为2.94Mbps&#xff08;后发展为10Mbps&#xff09;&#xff0c;主要用于解决…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...