KCP
KCP是一个基于UDP的可靠传输协议,其核心目标是在牺牲一定带宽利用率的前提下,尽可能降低传输延迟。它并非一个全新的传输层协议,而更像是在应用层对UDP数据包进行可靠性、顺序和流量控制的"增强外壳"。
其底层具体来说就是在UDP的基础之上,加入了TCP有的诸如拥塞避免,流量控制等保证可靠性传输的手段,也就是所谓的ARQ机制与窗口协议。
ARQ协议(Automatic Repeat-reQuest),即自动重传请求,是传输层的错误纠正协议之一,它通过使用累计确认和超时两个机制,在不可靠的网络上实现可靠的信息传输。
能够在不可靠的网络中传输可靠的数据,但这不意味着可以随意发送数据,带宽是有限的,接收方的负载也是有限的,所以引入了窗口协议,做流量控制。

KCP与TCP在ARQ和滑动窗口的实现上存在关键差异:
-
窗口控制的区别 :关键在于响应策略的激进程度。TCP作为标准协议,采用保守的"乘法减小"来保障全局网络公平;而KCP将控制权交给开发者,允许为追求速度而采用更激进甚至不退缩的策略。
-
ARQ机制的区别 :关键在于反馈的精度与触发的灵敏度。TCP依赖间接推断(超时或重复ACK),而KCP通过更低的触发阈值和直接报告(SACK/NACK),实现了更快速、更精准的重传。
二者核心区别在于反馈信息的精度和触发的灵敏度 。TCP的反馈像是说"第50页之前的都收到了"(但你不知道我到底缺了哪一页),而KCP的反馈则像说"第50页之前的都收到了,但我明确发现第35页丢了"。后者能让发送方毫无延迟、准确无误地重传丢失的数据,这是KCP实现低延迟的关键设计之一。
然而,这些优点是以牺牲部分带宽效率、缺乏TCP那样的网络全局公平性,以及需要应用层自行实现更复杂的连接管理和调优为代价的,这甚至牵扯到另一个问题:NAT穿透。因此KCP更适合应用于能容忍一定带宽冗余、但对延迟极度敏感的实时场景(如竞技游戏、实时音视频),而TCP则仍是需要绝对可靠、有序交付和公平共享网络资源的通用传输基石。
什么是NAT穿透问题?NAT穿透问题是指,当两个设备(如两位玩家的电脑)分别位于不同的私有局域网(如各自的家用路由器后)时,它们希望建立直接的端对端(P2P)连接,但中间的NAT设备(路由器)会阻止外部主动发起的连接请求,导致双方无法直接通信。这个问题对于基于UDP的协议(如KCP、QUIC)尤为突出,因为UDP是无状态的,NAT为它建立的临时端口映射会在短时间内过期,使得连接难以建立和维持。
解决NAT穿透的核心方法是"打洞",通常需要一个公网服务器协助,流程如下:首先,双方设备通过一个信令服务器 (使用TCP)交换各自的网络信息;然后,它们利用STUN服务器 或类似机制,探测自身在NAT上的公网IP和端口,并通过信令服务器交换这些地址;接着,双方几乎同时向对方的公网地址发送UDP数据包,此举能在各自的NAT上"凿开"一条允许数据进入的临时通道;连接建立后,还需定期发送保活数据包 以维持该通道不被NAT关闭。如果打洞失败(因严格的NAT类型),则需降级使用TURN服务器进行数据中转。这套组合策略(STUN/TURN/ICE)是WebRTC等现代P2P通信的基石。
在游戏开发中,KCP 主要被应用于对网络延迟和响应速度要求极为苛刻的实时对战类游戏。其核心价值在于,它通过牺牲部分带宽效率和网络公平性,换取了在复杂网络环境下更稳定、更低的传输延迟。
QUIC
QUIC是由Google主导开发的新一代传输层网络协议,旨在解决TCP的一些固有缺陷。它运行在UDP之上,但整合了TCP的可靠性、TLS的安全性和HTTP/2的多路复用等特性。
其底层依然基于UDP实现,但是和KCP不同之处在于,TLS 1.3 被深度集成到QUIC协议中。连接建立(握手)与加密协商合并 ,通常只需1-RTT甚至0-RTT即可建立安全连接,显著降低延迟。且该协议彻底解决了队头阻塞问题,在单个物理连接上,每个独立的逻辑数据流(Stream)都是有序的,但流与流之间互不阻塞。一个流的包丢失只会影响该流,不会拖累其他流(而TCP下同一个连接中一个包丢失会阻塞所有后续数据)。
其核心特性与工作原理如下:
1. 极速连接建立(0-RTT/1-RTT)
QUIC将传输和加密握手合二为一。首次连接时,客户端与服务器通过1个RTT完成密钥交换和连接建立。更关键的是,得益于TLS 1.3的会话恢复机制,之前连接过的客户端在重连时可以实现0-RTT握手,即第一个数据包就可以携带应用数据(如HTTP请求),极大提升了短连接场景(如网页访问)的响应速度。
2. 彻底解决队头阻塞的多路复用
这是QUIC相比TCP/HTTP/2最根本的改进之一。QUIC在单个连接上支持多个独立的、有序的字节流(Stream)。每个流的数据被封装在独立的QUIC数据包中。关键创新在于:每个数据包拥有全局唯一、单调递增的Packet Number,并且重传的数据包会使用全新的Packet Number。同时,每个数据帧通过Stream ID和Offset来标识其所属的流及位置。因此,当某个流的数据包丢失时,只会阻塞该流本身的重传和重组,其他流的数据包可以继续被接收、确认和处理,真正实现了流级别的并行,彻底消除了TCP层和应用层的队头阻塞。
3. 深度集成的安全性与前向保密
QUIC并非在UDP之上简单叠加TLS,而是将TLS 1.3深度集成到协议内部,几乎所有报文头部和有效载荷都经过认证和加密。这避免了TCP头部明文传输可能被中间设备(如防火墙、NAT)篡改或注入的问题,增强了隐私和安全性,也使得协议本身更容易演进(因为中间设备无法解析其内容)。同时,它默认提供前向保密(Forward Secrecy)。
4. 无缝连接迁移
TCP连接由四元组(源IP、源端口、目的IP、目的端口)标识,任何一变(如手机从Wi-Fi切换到4G导致IP变化)连接就会中断。QUIC使用一个64位的Connection ID来唯一标识连接。只要Connection ID不变,即使客户端的网络地址发生变化,连接也可以无缝迁移,上层应用完全无感知,这对移动场景至关重要。
5. 可插拔的拥塞控制与增强恢复机制
QUIC的拥塞控制算法实现在用户空间,而非操作系统内核。这意味着它可以更灵活地更新和优化,甚至能为不同连接配置不同的算法(如Cubic、BBR)。此外,QUIC的ACK帧支持携带多个丢失数据包的范围信息,并提供更精确的RTT测量,使得丢包检测和恢复比TCP的快速重传/快速恢复机制更高效。部分实现还支持前向纠错(FEC),通过发送冗余数据,在少量丢包时无需重传即可恢复,进一步优化弱网体验。
Websocket
WebSocket是一种在单个TCP连接上提供全双工、双向通信 的应用层协议。它主要解决了HTTP协议"请求-响应"模式不适合实时、持久通信的问题。
WebSocket的底层原理始于一个基于HTTP的"握手"升级请求:客户端向服务器发送一个带有Upgrade: websocket等特定头部的HTTP请求,服务器验证后返回101状态码表示协议切换成功。此后,双方脱离HTTP的请求-响应范式 ,在原有的TCP连接上使用轻量级的WebSocket数据帧进行通信。这种数据帧格式开销极小(最小仅2字节头),支持区分文本/二进制数据及控制指令(如Ping/Pong心跳、关闭握手),从而在单个持久化的TCP连接上实现了全双工、低开销的双向实时通信,使得服务器可以随时主动向客户端推送消息,完美解决了HTTP在实时交互场景中的瓶颈。