[LWIP] LWIP热插拔功能 问题调试

实现了LWIP网络热插拔的功能,但是也出现了一个问题

出现的问题

每次拔掉网线再插上,虽然能重新连接,但是通过调试信息发现每拔插一次网线,上一次的active pcb仍然存在,在拔插3次后,再次连接能够连接成功,但是已经无法通信。通过输出的调试信息查看如下,tcp定时器每次都会处理3个active pcb,而且是最多3个 不会再增加

bash 复制代码
[2025-12-27 19:47:00.604]# RECV ASCII>
tcp_slowtmr: processing active pcb
tcp_slowtmr: polling application
tcp_slowtmr: processing active pcb
tcp_slowtmr: polling application
tcp_slowtmr: processing active pcb
tcp_slowtmr: polling application

原因

检测到网线断开后没有释放资源,但是再次连接网线tcp还能重新连接上。

PCB = Protocol Control Block(协议控制块)

在 LwIP 中,PCB 是网络协议的控制数据结构,用于管理连接状态、缓冲区、定时器等。不同类型的协议有不同的 PCB:TCP PCB:管理 TCP 连接(包含发送/接收窗口、序列号、状态等)

可能的原因1:不是 TCP PCB 数量限制和相关内存池配置

我的工程中关于TCP PCB 数量限制和相关内存池配置 如下

cpp 复制代码
#if !defined MEMP_NUM_TCP_PCB || defined __DOXYGEN__
#define MEMP_NUM_TCP_PCB                5
#endif

#if !defined MEMP_NUM_TCP_PCB_LISTEN || defined __DOXYGEN__
#define MEMP_NUM_TCP_PCB_LISTEN         8
#endif


#if !defined MEMP_NUM_TCP_PCB || defined __DOXYGEN__
#define MEMP_NUM_TCP_PCB                5
#endif

#if !defined MEMP_NUM_TCP_SEG || defined __DOXYGEN__
#define MEMP_NUM_TCP_SEG                16
#endif

配置数量都在3以上,应该是其他原因

可能的原因2:不是 内存空间问题

尝试修改lwip内存空间分配,由3000改为1000

cpp 复制代码
#if !defined MEM_SIZE || defined __DOXYGEN__
#define MEM_SIZE                        3000
#endif

改为

#if !defined MEM_SIZE || defined __DOXYGEN__
#define MEM_SIZE                        1000
#endif

修改后现象仍然是最多3个active pcb,没有变化

原因3 不是

#if !defined IP_REASS_MAXAGE || defined DOXYGEN

#define IP_REASS_MAXAGE 2

#endif

由3改为2,现象没有变化

原因4 不是

#if !defined ARP_QUEUE_LEN || defined DOXYGEN

#define ARP_QUEUE_LEN 2

#endif

由3改为2,现象没有变化

过程为连接网线并开机-》TCP连接读取数据 -》第一次拔插-》TCP连接读取数据-》第二次拔插-》TCP连接读取数据-》第三次拔插-》读取数据失败。

原因5 modbus tcp定义

在lwip之上使用了freemodbus 的modbus-tcp。在文件porttcp.c中有如下定义

cpp 复制代码
#define MB_TCP_CLIENTS  3

将定义数量由3改为2后,最多连接2次,就不能读取数据了。

把数值改为6 #define MB_TCP_CLIENTS 6

在第六次TCP连接时弹出如下调试信息,应该是达到了最多TCP连接限制。

复制代码
[2025-12-27 21:21:19.883]# RECV ASCII>
tcp_slowtmr: processing active pcb
tcp_slowtmr: polling application
tcp_slowtmr: processing active pcb
tcp_slowtmr: polling application
tcp_slowtmr: processing active pcb
tcp_slowtmr: polling application
tcp_slowtmr: processing active pcb
tcp_slowtmr: polling application
tcp_slowtmr: processing active pcb
tcp_slowtmr: polling application
tcpip_thread: PACKET 20008a60
tcpip_thread: PACKET 20008a60

[2025-12-27 21:21:20.085]# RECV ASCII>
tcpip_thread: PACKET 20008a60
tcpip_thread: PACKET 20008a60
TCP connection request 50378 -> 503.
tcpip_thread: PACKET 20008a60
Assertion "tcp_input: pcb->next != pcb (before cache)" failed at line 236 in ..\LwIP\src\core\tcp_in.c
Assertion "tcp_input: pcb->next != pcb (after cache)" failed at line 244 in ..\LwIP\src\core\tcp_in.c
TCP connection established 50378 -> 503.

解决办法

tcp数量不能无限多,那么就需要在断开连接时对资源进行释放。

相关推荐
笑鸿的学习笔记17 分钟前
C++笔记之SIMD与SSE指令集
开发语言·c++·笔记
福兮说35 分钟前
URL 编码的七个坑:c++ 传到后端变空格、%25 套娃、截断 emoji 直接报错
开发语言·前端·javascript·node.js·url
小的时候可菜了1 小时前
JS 异步的本质:从单线程到 thenable(一条进化链)
开发语言·前端·javascript
一条破秋裤1 小时前
TCP 套接字:API 流程、地址结构与网络字节序
网络·tcp/ip·php
可乐鸡翅yeah_1 小时前
hls.js 配置 loadStartPosition,点播起始播放位置踩坑
开发语言·javascript·网络协议·ecmascript·m3u8在线
en.en..1 小时前
Linux 进程退出exit(函数)
java·开发语言·算法
Cx330❀1 小时前
【Qt 进阶指南】详解 Qt 常用标准对话框与主窗口组件架构
开发语言·qt·ui·性能优化·架构·图形渲染
Light Gao1 小时前
Encoder 与 Decoder 详解:从 Embedding 到 Seq2Seq 的完整数据流
java·开发语言·embedding
HZZD_HZZD1 小时前
弱网下CoAP还省吗?合众致达Cat.1电表90天实测:MQTT重连流量占52%、续航差距从38%拉大到73%
开发语言·物联网·php·腾讯云
web打印社区1 小时前
Windows 网页静默打印设置步骤:客户端、防火墙与联调清单
开发语言·前端·javascript·chrome·pdf·ecmascript