重新设计 TCP 协议

news2024/11/16 7:55:27

看一段关于 TCP 协议的历史讨论,源自:The design philosophy of the DARPA internet protocols
在这里插入图片描述
读这段文字时,你可能觉得这不是在谈 TCP,而是在创造一个新协议,但事实上这就是 TCP 在被创造过程中真实的纠结。

现在来看,TCP 就是 RFC793 所描述的一个固定格式且简单的协议,它最终是把端到端逻辑和传输做到一起了,但一开始并不是这样。一开始 IP 并没有从 TCP 分离,IP 的功能被 TCP 承载,TCP/IP 作为一个协议来理解,一切明了。

端到端的 TCP 体现在保序和流控,而传输则交给了 IP 数据报,与传输相关的拥塞控制应由 IP 数据报负责,与保序和流控无关。

剥离了 IP 后的 TCP 即 byte-based stream,而负责传输的 IP 则为 packet-base datagram,1986 年后引入的 TCP 拥塞控制基于 byte-based stream 进行修正,注定会带来各种难题以及针对这些难题的各种非正式 trick,典型的问题即,TCP 分不清楚原始报文的 ACK 和重传报文的 ACK,因此会存在伪重传,针对伪重传引入了 Eifel 算法以及复杂的 dsack,undo 等机制,同时 RTT 测量也因此存在歧义。

但这些真实必要吗?

回到最初的设计阶段,如果重新设计 TCP 协议,一开始就考虑内置拥塞控制,穿越回转的 TCP 又会是什么样子?或者说,现在我们知道了 TCP 协议的各种问题之后,重新设计一个新的协议,它会是什么样子?

首先说下 UDP。

说到 UDP 的意义,很多人认为它不检测丢包,不重传,适合实时传输,比 TCP 快,诸如此类,但事实上没有任何应用偏好丢包,所谓不 care 丢包只是程度问题而非是非。UDP 的意义在于它是一个真正的分组交换网的传输抽象,UDP 本身就是数据报分组。

换句话说,网络上适合传输 UDP 数据报,而不适合传输 TCP 数据流。这是一个后见之明。当 TCP/IP 被标准化时,分离后的 TCP 已经在那里了:
在这里插入图片描述
以现在的眼光看,TCP 确实不适合直接在 IP 之上进行传输,以分层后的 TCP/IP 来看,TCP 需要一个传输抽象,即它应该被封装在 UDP 数据报里进行传输:
在这里插入图片描述
​拥塞控制本应该引入到 IP,而不是 TCP,基于 IP 数据报做拥塞控制要比基于 TCP 流做拥塞控制容易得多。

我们现在设计拥塞控制算法时,常常提到 TCP 友好性,意思是某种传输协议对 TCP 的侵占,比如 UDP 就是 TCP 不友好的协议,UDP 流量很容易榨干带宽资源,因为它没有内置拥塞控制。让我们仔细揣摩这个现实,到底问题出在哪?凭什么 UDP 没有内置拥塞控制而 TCP 却必须要进行拥塞控制?

问题在于,拥塞控制本来就应该不区分传输层协议,它本就应该部署在 IP 层,作用于每一个 IP 数据报,而不是 TCP 数据流。如果对 IP 数据报一视同仁,那么无论 TCP 还是 UDP 便被纳入同一个系统中,难题也就不再是难题。

将 TCP 字节流封装到 UDP 数据报,则 TCP 仅剩下端到端保序和流控等传输控制逻辑,这是高尚的。

打个比方,当你需要运输一批大宗货物或零担货物,用什么容器,用多大规格容器来装这些货物是不需要货主操心的,货主甚至从头到尾对此一无所知,但无论运输什么货物,都需要使用集装箱,运输公司只需要提供集装箱,而货主则需要注明轻拿轻放,哪头朝上,并且支付保费即可,如果一些无所谓损毁遗失的货物,便不需要支付保费。同样的道理在 TCP/IP 依然适用。

传输层仅提供 UDP 集装箱,TCP 提供字节序列号并叮嘱 UDP/IP 一旦丢失序列号,必须重传。剩下的传输工作,交给 UDP 即可。

QUIC 就是这样一个 TCP/UDP/IP 协议,但它太重了,QUIC 是一个集大成的大协议(MPTCP 也是),但这个大协议是可以通过组合模式组装起来的。

我来试个简单的做法,将传输逻辑从 TCP 中分离出来:

  • TCP 保序和流控使用 byte-based stream 在端到端实现,按照 byte stream 组织字节。
  • TCP 传输使用 packet-based datagram 实现,交给 UDP,按照 packet seq 进行传输和确认。

看一下具体的设计。

struct packet {
    struct udphdr udp_hd;
    struct tcp_payload
    struct attribute {
        uint trans_seq;
        uint64 timestamps;
    } attr;
    // 以下字段用来组织数据结构,不参与传输
    struct list_head list; // 索引该 packet 的发送顺序
    struct rbtree rb; // 基于 ACK attributes 查找 packet
};

将传输过程作为报文的属性 “粘贴在箱子上”,箱子和货物分离,箱子上只粘贴和传输相关的信息,对内部 TCP 报文透明,同一个 packet,无论第一次传输还是重传,均会被贴上不同的传输属性,同时组织进发送端数据结构以便被索引。

以下是一个传输传输示意图:
在这里插入图片描述
对于接收端,以 UDP 数据报作为接收单位,按照其 payload 组织保序,并且根据 packet 而不是 byte stream 生成 ACK。注意,新协议确认 packet,而不是确认 stream:
在这里插入图片描述
发送端收到 ACK 后的反应也因此变得简单:
在这里插入图片描述
最初的 TCP 基于 byte stream 而不是 packet 进行传输确认(见文初的引图),其中一个理由是可以合并重传,但在新协议中,由于设计基础发生了根本改变,基于 packet 进行传输确认也很容易进行合并重传:
在这里插入图片描述
这个设计可以复用大量 TCP 现有的代码,几乎只是需要删减一些逻辑即可。将 byte-based ACK 改为 packet-based ACK 大大降低了实现的复杂程度。

最后我们来看看这个新设计有没有解决 TCP 的固有问题。

首先,ACK 歧义肯定是解决了,拥塞控制肯定是简易了,可 HoL 阻塞解决了吗?显然没有。只要 TCP 还是保序的,基于滑动窗口的停-等是保序的基础,那么 HoL 阻塞就是注定的,如果后面的数据先到达也能交付,那就不叫保序协议了。

其次,中间节点对 TCP 的固有假设可以放弃了吗?固有假设让 TCP 只能是 TCP 而不能升级。新协议显然缓解了该问题,ACK 采用 TLV 格式,提高了固有假设的难度,让固有假设成本更高。但深入思考该问题,这其实是典型的借力打力,固有假设恰恰违背了端到端原则,而 TCP 恰恰希望端到端解决一切问题。

回到新 TCP 依然存在的问题以及其解决方案本身,QUIC 到底是不是一个好协议?

显然,通过组合不同的组件,我这个新协议完全可以组合成 QUIC 协议的等价协议,可以捆绑多条流,可以修改源 UDP 端口,可以 Multi-Path,可以叠加 DTLS,诸如此类吧。所以,什么是 QUIC?名字重要吗?

这个想法思考很久了,像往年一样,大年二十九就出门了,直接在外面过除夕和春节,酒店里点了肯德基全家桶当年夜饭,顺便写了这篇文字。有点长,白天从云上草原,南浔古镇,一直到拈花湾,只有晚上回到酒店有时间,分了两天才写完。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/176093.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java知识点细节简易汇总——(6)面向对象编程(中级部分)

一、IDE快捷键 删除当前行, 默认是 ctrl Y 自己配置 ctrl d复制当前行, 自己配置 ctrl alt 向下光标补全代码 alt /添加注释和取消注释 ctrl / 【第一次是添加注释,第二次是取消注释】导入该行需要的类 先配置 auto import , 然后使用 altenter 即可快速格式化…

Day867.事务隔离 -MySQL实战

事务隔离 Hi,我是阿昌,今天学习记录的是关于事务隔离的内容。 提到事务,肯定不陌生,和数据库打交道的时候,总是会用到事务。 最经典的例子就是转账,你要给朋友小王转 100 块钱,而此时你的银行…

[前端笔记——CSS] 10.层叠与继承、选择器

[前端笔记——CSS] 10.层叠与继承、选择器1.层叠与继承1.1 冲突规则1.2 继承1.3 层叠1.4 CSS位置的影响2.选择器2.1 选择器是什么?2.2 选择器列表2.3 选择器的种类类型、类和 ID 选择器标签属性选择器伪类与伪元素运算符选择器参考表1.层叠与继承 1.1 冲突规则 CS…

一起自学SLAM算法:8.1 Gmapping算法

连载文章,长期更新,欢迎关注: 下面将从原理分析、源码解读和安装与运行这3个方面展开讲解Gmapping 算法。 8.1.1 Gmapping原理分析 首先要知道,Gmapping是一种基于粒子滤波的算法。在7.7.2节中已经提到过用RBPF(Rao-…

linux系统中使用QT实现APP开发的基本方法

大家好,今天主要和大家分享一下,如何使用QT进行APP的主界面开发的方法。 目录 第一:APP界面开发基本简介 第二:滑动界面实现 第三:APP界面开发实现 第四:APP主界面测试 第一:APP界面开发基本…

ARP渗透与攻防(一)之ARP原理

ARP原理 前言 ARP攻击就是通过伪造IP地址和MAC地址实现ARP欺骗,能够在网络中产生大量的ARP通信量使网络阻塞,攻击者只要持续不断的发出伪造的ARP响应包就能更改目标主机ARP缓存中的IP-MAC条目,造成网络中断或中间人攻击。ARP攻击主要是存在…

CSS3基础内容

目录 CSS基本样式 选择器分类 标签选择器 类选择器 利用类选择器画三个盒子 多类名 id选择器 id选择器和类选择器的区别 通配符选择器 CSS字体属性 字体粗细font-weight 字体样式 CSS文本属性 CSS的引入方式 行内样式表(行内式) 内部样式表…

2023年集卡活动简记

文章目录支付宝总评:【强烈推荐】年味浓,必中奖,单倍金额不算少。只关注开奖可以除夕当天玩儿。集卡分1.88元难度:【非常低】必中奖时间投入:【较少】无需打开其他App,比较轻松。操作体验:【好】…

深度理解卷积神经网络

神经网络包括卷积层,池化层,全连接层。一个最简单的神经元结构,假如有三个输入,都对应一个权重参数,然后通过权重加起来,经过一个激活函数,最后输出y。CNN中独特的结构就是卷积层,就…

拓展:阿里巴巴中文站架构演进分析【部分】

文章目录前言阿里巴巴中文站架构发展历程阿里巴巴第五代架构数据架构的复杂前言 由学习整理而来,并非有意抄袭。如果有冒犯行为,请及时联系作者进行处理! 阿里巴巴中文站架构发展历程 时间关键技术1999第一代网站架构Perl,CGl&…

【实操案例八】元组、集合操作 实例代码及运行效果图!

任务一:我的咖啡馆你做主 方法一:使用列表 # 任务一:我的咖啡馆你做主 # 方法一:使用列表lst[蓝山,卡布奇诺,拿铁,皇家咖啡,女王咖啡,美丽与哀愁]for i in lst:print(lst.index(i)1,.,i,end\t) print()while True:chice int(in…

SpringCloud+Ribbon 报错:java.net.unknownhostexception:XXX

SpringCloudRibbon 报错:java.net.unknownhostexception:XXX 问题分析: 网上很多的说法是依赖冲突导致,原因是什么呢:如果你的org.springframework.cloud:spring-cloud-starter-netflix-eureka-client 依赖中包含了ribbon依赖&…

常用JVM配置参数简介

既然学习JVM,阅读GC日志是处理Java虚拟机内存问题的基础技能,它只是一些人为确定的规则,没有太多技术含量。 既然如此,那么在IDE的控制台打印GC日志是必不可少的了。现在就告诉你怎么打印。 (1)如果你用的是…

Elasticsearch7.8.0版本高级查询—— 分页查询文档

目录一、初始化文档数据二、分页查询文档2.1、概述2.2、示例一、初始化文档数据 在 Postman 中,向 ES 服务器发 POST 请求 :http://localhost:9200/user/_doc/1,请求体内容为: { "name":"zhangsan", "ag…

数据分析-深度学习 Pytorch Day8

一。什么是循环神经网络:循环神经网络(Rerrent Neural Network, RNN),历史啊,谁发明的都不重要,说了你也记不住,你只要记住RNN是神经网络的一种,类似的还有深度神经网络DNN&#xff…

广州周立功CanTest卡使用教程一

网上有不少Can采集平台,包括Ardunio,Can卡,也有不少人用Freescale自己DIY一个平台,这些都是相当不错,并且都有成熟的代码,这里介绍在汽车诊断软件领域普遍都会选择的Can卡使用。 大家是不是对这个节面非常熟悉,CAN-bus 通用测试软件是一个专门用来对所有的 ZLGCAN 系列板…

【Python】基于经典网络架构训练图像分类模型——图像识别模型与训练策略(2023年1月22日,大年初一,春节快乐,兔年大吉)

声明:仅学习使用~ 今天是大年初一,祝大家新年快乐!!! 这个练习使用的图片稍多,因此初次在PyCharm里面可能会需要一些时间。 (注释中包含遇到的一些错误以及修正,同时也含有一些输出,部分较长的输出以省略号的形式在注释里面展示了) 2023.1.22,大年初一,新年快乐…

LoadBalancer源码解析

文章目录一、背景二、总体流程三、源码解析1. lb拦截器配置2. LB拦截器实现3. LB执行前置处理4. 负载均衡5. LB执行http请求一、背景 Spring Cloud 2020版本以后,默认移除了对Netflix的依赖,其中就包括Ribbon,官方默认推荐使用Spring Cloud …

生物化学 电阻抗成像OpenEIT 番外篇 EIT公式

EIT简介 摘要电阻抗断层扫描(EIT)是一种成像方式,使用无害的电流探测患者或物体。电流通过放置在靶表面上的电极馈送,数据由在电极处测量的电压组成,这些电压由一组线性独立的电流注入模式产生。EIT旨在恢复目标内部电…

【MySQL】第八部分 加密和解密函数

【MySQL】第八部分 加密和解密函数 文章目录【MySQL】第八部分 加密和解密函数8. 加密和解密函数总结8. 加密和解密函数 函数用法PASSWORD(str)返回字符串str的加密版本,41位长的字符串。加密结果不可逆,常用于用户的密码加密.( 8.0 版本以上不能用)MD5…