news 2026/11/5 2:06:28

dpdk实现tcp滑动窗口-阶段1

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
dpdk实现tcp滑动窗口-阶段1


仓库:https://gitee.com/fan-junchuang/1010-dpdk


rwnd、cwnd、swnd、BIF这四个在一个tcp报文中的体现就是wind size、seq、ack这三个字段。

window scale体现在tcp报文中option中。


struct tcp_conn{ /* 发送窗口 */ uint32_t iss; // 初始序列号,SYN 占用 iss uint32_t snd_una; // 最早未被确认的序列号 uint32_t snd_nxt; // 下一个待发送序列号(已被 nsend 分配,可能还在队列里) uint32_t snd_max; // 已经真正发到网线上的下一个序列号(纯 ACK 的 seq 用它) uint32_t snd_wnd; // 对端通告的窗口 // MTU(1500) - etherhdr(8) - iphdr(14) - tcphdr(20) = 1460 uint32_t snd_mss; // 本端发送 MSS 本端发送方向的最大报文段长度 /* 接收窗口 */ uint32_t rcv_nxt; // 期望收到的下一个序列号 uint32_t rcv_wnd; // 本端接收窗口,通告给对端 };

首先看我们实现了什么,实现了一个结构体struct tcp_conn,

里面的参数都是和窗口有关的,是实现滑动窗口、拥塞控制、慢启动等的基础。

snd_una、snd_max、snd_nxt将发送队列分成了四个部分。

示意图如下。

已发送已确认 已发送未确认 马上发送 暂时不发送 ──────────────┼────────────┼───────────┼───────────────► │ │ │ snd_una snd_max snd_nxt snd_una + swnd (左沿) (线上沿) (分配沿) (右沿)
参数归属: snd_una ── 窗口左沿,由对端 ack 推进 snd_max ── 已上线沿,由 tcp_pkt_send 推进,纯ACK的seq用它 snd_nxt ── 已分配沿,由 nsend/nclose 入队成功后推进 snd_wnd ── 对端 rwnd,报文 window 字段来 swnd=min(cwnd,snd_wnd) cwnd ── 右沿的另一半,本端拥塞窗口(当前缺字段!) rcv_wnd ── 不是这四个区域的参数,是本端通告给对端的窗口 iss ── 整个序列号空间的原点,snd_una/snd_nxt/snd_max 初值 snd_mss ── 区域3→2 每次搬多少字节的上限(分段用,当前未接线)
已发送已确认 ——[0, snd_una)

这些字节对端已经 ACK,本端可以彻底丢弃。

snd_una是这个区域的右边界,也是"滑动窗口左沿"。

已发送未确认 ——[snd_una, snd_max)

这些字节已经真正发到网线上,但对端还没 ACK。它们是在途字节(BIF, bytes in flight)

BIF = snd_max - snd_una

这个区域是重传定时器(RTO)的作用范围:超时后从snd_una重发到snd_max。

马上发送 ——[snd_max, snd_nxt)

这些字节已经被nsend分配了序列号、拷进了 sendbuf 队列,但还没被tcp_pkt_send取出来发到网线。它们"马上要发"。

暂时不发送 ——[snd_nxt, snd_una + swnd)

这些字节还没被分配序列号(还没nsend)


纯 ACK 报文不消耗序列号(SYN/FIN 各消耗 1 个序号,data 消耗 len 个序号):

**序列号(Sequence Number)**‌: 自己下一次要发送的起始序号 。

seq=自己已经发送的数据 之后一个的序号

对于携带数据的报文:

**序列号(Sequence Number)**‌: 自己这次发送数据中的第一个数据的序号 。

seq=本段第一个数据字节的序号

对于携带数据又携带ack的报文 和 上面携带数据的报文中seq定义一样。

**确认号(Acknowledgment Number)**‌:期望对方下一次从这个起始序号开始发送。

ack=自己期望从对方收到的下一个序号


报文字段本端变量
seq发送时填snd_nxt(数据段)/snd_max(纯 ACK)
ack接收时推进snd_una;发送时填rcv_nxt
window接收时存snd_wnd;发送时填rcv_wnd

在nsocket时,创建server entry时需要create server tcpcon。

在listen cd中,create clietn entry,也需要create client tcpcon。

在tcp server端nsendto时候,更新snd nxt。

在把数据写入out ring时,更新snd max。


iss就是第二次握手发送的初始seq,常值。

在初始化时,snd_una、snd_max、snd_nxt三个值都相等都是iss。


从接收和发送数据的视角看:

如果接收的是第一次握手SYN,需要更新snd_wnd,rcv_nxt。

seq = iss;

ack = ntohl(tcphdr->sent_seq) + 1;

rcv_nxt = ack;

如果接收到的是纯ack包,需要更新snd_una,snd_wnd。

snd_una = ack;

snd_wnd = ntohs(tcphdr->rx_win);

如果接收的是数据包并且携带ack,需要更新snd_wnd,rcv_nxt,snd_una。

snd_una = ack;

snd_wnd = ntohs(tcphdr->rx_win);

rcv_nxt += payloadlen;

当发送纯ack时,不需要更新。

seq = snd_max;

ack = rcv_nxt;

当发送数据,在nsend中把数据加入sendbuf,需要更新snd_nxt。

seq = snd_nxt;

ack = rcv_nxt;

snd_nxt += len;

当发送的数据加入out ring进行发送后,需要更新snd_max。

snd_max = seq + len;


从参数的视角看:

snd_una:

初始化为iss。

只有接收到ack时才会更新。

snd_una = acknum。

snd_max:

初始化为iss。

在数据发送出去后才会更新。

snd_max = seqnum + len;

snd_nxt:

在数据接入到sendbuf后才会更新。

snd_nxt += len;

rcv_nxt:

只要接收到数据就要更新。

rcv_nxt += len;

snd_wnd:

只有接收到ACK才会更新。

snd_wnd = ntohs(tcphdr->rx_win);


文章参考<零声教育>的C/C++linux服务期高级架构系统教程学习:0voice · GitHub

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/5 2:06:28

3个实力派降AI率软件,让你的论文轻松过关AIGC检测[必看]

最近后台被不少同学刷屏&#xff0c;说论文明明是自己一字一句敲出来的&#xff0c;就用AI帮忙理了理框架、捋了捋逻辑&#xff0c;结果提交前一查&#xff0c;AIGC检测率直接冲到30%以上&#xff0c;整个人都懵了。这真不是个例&#xff0c;现在各大高校和查重平台陆续上线AI识…

作者头像 李华
网站建设 2026/11/5 2:06:22

我用 WorkBuddy + Lexmount 整理招聘信息:从网页读取到岗位对照表

三个名字里都带着“AI”的岗位&#xff0c;放到一起看&#xff0c;做的事却差得挺远&#xff1a;一个偏海外增长&#xff0c;一个做企业里的 Agent 平台&#xff0c;一个做游戏中的 AI 模块。 这次我用 WorkBuddy 搭配 Lexmount 云浏览器&#xff0c;把腾讯招聘官网的三个深圳…

作者头像 李华
网站建设 2026/11/5 2:06:22

机器人很热闹,但乌镇真正的主角没上台

《机器人很热闹&#xff0c;但乌镇真正的主角没上台》 ——真正改变生产力的&#xff0c;不是会打拳的机器&#xff0c;而是把想法兑换成现实的速度乌镇今年最红的展品&#xff0c;是一位“拳击手”。它出拳、侧闪、一记高踢&#xff0c;落地还能扎稳马步&#xff0c;引来一片惊…

作者头像 李华
网站建设 2026/11/5 2:05:57

5、eureka集群环境搭建

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/5 2:05:03

污染 0.1% 的语料,编程智能体 92% 执行陌生命令|2026年11月04日

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/5 2:04:59

4-1静态数码管显示

本次学习有很多知识点&#xff0c;我将分条总结 一.单个数码管单个数码管分为共阴极和共阳极&#xff0c;第一个电路是共阴极数码管&#xff0c;若使这个数码管可使用&#xff0c;3.8那边应该接阴极&#xff0c;第二张图是共阳极数码管&#xff0c;若使数码管可用应在3.8那边接…

作者头像 李华