LWIP TCP滑动窗口为TCP ZeroWindow的解决方法

LWIP TCP滑动窗口为TCP ZeroWindow的解决方法

    正在检查是否收录...
一言准备中...

最近做项目使用到LWIP, 板子当作客户端,PC机当作服务器,当板子和PC机通信一段时间后,板子就接收不到数据。抓包分析为:
image

发现经过一段时间通信后,滑动窗口大小越来越小,最终显示为TCP WINDOW FULL,TCP ZeroWindow。 仔细分析了下LWIP源码,还以为是内存管理出了问题,跟踪了半天memp.c也没发现问题。后来发现问题出现自己的应用实现代码,下面是我这边的实现代码:

 err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { if (err != ERR_OK) { RLOG_ERROR("Error in tcp_client_recv: %d\n", err); tcp_client_close(tpcb); // 关闭连接 return ERR_OK; // 释放 pbuf } if (p != NULL) { // 处理接收到的数据 char *data = (char *)p->payload; int datalen = p->len; // 安全地复制数据 char buff[datalen + 1]; memcpy(buff, data, datalen); buff[datalen] = '\0'; // 打印接收到的数据 //RLOG_INFO("Received data: %s\n", buff); // 释放 pbuf pbuf_free(p); RLOG_INFO("pbuf freed\n"); } tcp_output(tpcb); return ERR_OK; } 

上面的代码,需要在接受数据后,主动调用tcp_recved(tpcb, p->tot_len) ,修改代码后,再次验证功能正常。
修改后的代码:

 err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { if (err != ERR_OK) { RLOG_ERROR("Error in tcp_client_recv: %d\n", err); tcp_client_close(tpcb); // 关闭连接 return ERR_OK; // 释放 pbuf } if (p != NULL) { // 处理接收到的数据 char *data = (char *)p->payload; int datalen = p->len; // 安全地复制数据 char buff[datalen + 1]; memcpy(buff, data, datalen); buff[datalen] = '\0'; // 打印接收到的数据 //RLOG_INFO("Received data: %s\n", buff); tcp_recved(tpcb, p->tot_len); // 释放 pbuf pbuf_free(p); RLOG_INFO("pbuf freed\n"); } tcp_output(tpcb); return ERR_OK; } 

修正后运行效果:
image

原来,tcp_recved(tpcb, p->tot_len) 的主要作用是通知 TCP 层应用程序已经处理了指定长度的数据。这有助于 TCP 层调整接收窗口,避免接收缓冲区溢出,并确保数据传输的高效性。如果忘记调用这个函数,可能会导致接收窗口过小,影响数据传输效率。

  • 本文作者:WAP站长网
  • 本文链接: https://wapzz.net/post-27331.html
  • 版权声明:本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。
本站部分内容来源于网络转载,仅供学习交流使用。如涉及版权问题,请及时联系我们,我们将第一时间处理。
文章很赞!支持一下吧 还没有人为TA充电
为TA充电
还没有人为TA充电
0
  • 支付宝打赏
    支付宝扫一扫
  • 微信打赏
    微信扫一扫
感谢支持
文章很赞!支持一下吧
关于作者
2.7W+
9
1
2
WAP站长官方

ydswin

上一篇

记录win11下,WPF设置 System.AppUserModel.PreventPinning 属性用于阻止用户将应用程序固定到任务栏

下一篇
评论区
内容为空

这一切,似未曾拥有

  • 复制图片
按住ctrl可打开默认菜单