Files
CPP_Core/Core/transmit_protocol/协议分析文档.md
T
2026-06-16 10:56:40 +08:00

6.1 KiB
Raw Blame History

依赖协议类型

协议 流/包 必达性 顺序保证 数据正确性
串口
RTP(裸)
以太网帧
IPIPv4/IPv6 (IP 协议本身只保证头部完整性,并不保证数据区无损坏)
UDP
TCP
USB Bulk
KCP
SCTP(多流)

所有数据协议都是这种结构, 可以基于此协议实现(包/流) 特性的协议

枚举物理特性类型

类型 特点 例子
网络拥堵型 (Congestion-prone) 数据量接近带宽上限时会拥堵、排队、丢包,延迟增加 以太网、IP 网络、交换机/路由器链路
稳定误码型 (Constant Error Rate) 错误率稳定,发送速率不影响误码率 串口(UART/RS-232)、光纤点对点链路
高延迟型 (High Latency) 延迟几乎固定,带宽可能大,但 ACK/重传回路很慢 卫星通信、深空探测链路(NASA 深空网络)、洲际光缆
抖动型 (Jitter-prone) 传输延迟不稳定,包延迟波动大,适合平均速率控制,不适合严格定时 无线链路(4G/5G/Wi-Fi)、共享交换机低优先级端口
突发丢包型 (Burst Loss) 丢包连续发生,需 FEC(前向纠错)或交织(Interleaving)抵抗 无线广播、多播视频流、光纤瞬间闪断
自适应速率型 (Rate Adaptive) 链路带宽动态变化,需快速检测并调整传输速率 DSL、Wi-Fi(MCS 调制速率变化)、移动蜂窝网络
半双工限制型 (Half-duplex) 同一时刻只能收或发,需要收发切换时机,ACK/数据抢占带宽 老式对讲机、RS-485 总线、卫星上行/下行同频时分
多路径干扰型 (Multipath Fading) 信号多路径到达互相干扰,误码集中在特定时间段,需频率跳变或纠错码 移动无线通信、海面反射、建筑反射

物理特性抽象

虽然物理特性种类繁杂,但是我们只能应用软件手段,软件手段有以下几种 1.抗差错编码 2.拥塞控制 传输给物理链路数据的 频率,速度,大小等

kcp协议的底层依赖是udp类型的协议,一种无序,分包,非必达,保证数据正确的协议。 其中抗差错编码就可以做在这个底层协议上,外包给别人做。 kcp可以只专注于拥塞控制,对外提供可靠传输

所以这些物理特性总体来看可以看做可靠性和其他特性的关联函数 又分为两类 一类是 误码率与拥塞控制相关, 这是应该控制发包的流速调整方向和相关方向一致 一类是 误码率与拥塞控制无关, 这是应该忽略影响,尽量达到最大流量限制

KCP最佳实践

rto策略 真实使用rto msg->rto 1、kcp->rx_rto 全局的参考 RTO 基准值 是msg->rto初始值 根据网络抖动、均值,更新 实现在static void ikcp_update_ack(ikcpcb *kcp, IINT32 rtt) 2、msg->rto 根据丢包自动增长策略(kcp->nodelay控制) resendts是一个确切的重传时间点 根据 current 和 rto

kcp xmit 记录重传的次数,包括快速重传

kcp快速重传判断机制 ikcp_parse_fastack() 这里面增加 msg->fastack msg->fastack 快速重传权重值 kcp->fastresend; 快速重传阈值,msg->fastack达到这个值就重传一次 kcp->fastlimit 快速重传最大次数

kcp丢包判断机制 每个包都有自己的 msg->rto 倒计时器 如果当前时间 current >= seg->resendts(重传时间戳),就认为确实丢包了

我改成了最大值,使得快速重传无次数限制 const IUINT32 IKCP_FASTACK_LIMIT = -1; // max times to trigger fastack

send 发送是先进队列 再进 snd_buf

recv 发送是先进buf 再进 队列

snd_buf 是 已经发送出去但还没收到 ACK 的包的链表(按 sn 从小到大排序) rev_buf 是 未与rcv_nxt做连接的,非等间隔递增 ACK 的包的链表

// 这三个变量分析 snd_una 含义:最早未被确认(ACK)的发送序号 由ikcp_shrink_buf更新,从snd_buf取出最左边的处理 snd_nxt 含义:下一个要发送的序号 rcv_nxt 含义:接收方期望收到的下一个序号

kcp 回绕问题 KCP 的解决方法 KCP 里所有序号比较都不会直接用 sn1 > sn2 这种逻辑,而是用 _itimediff(a, b) static inline long _itimediff(IUINT32 later, IUINT32 earlier) { return ((IINT32)(later - earlier)); }

KCP 的序号比较是环形空间,假设包延迟或乱序不会超过 2^31 序号跨度(约 21 亿包),那么判断是安全的。

TCP 序号回绕机制与冲突避免策略