LWIP tcp服务器,网线不断插拔,服务器不断重连,最后连不上甚至死机
1.STM32芯片,tcp服务器,网线连接时候,客户端不断重连可以正常稳定连接。
2.客户端不断重连时候,网线不断断开重连,最后客户端连不上,甚至程序直接死机。
通过仿真发现err_t tcp_server_accept(void *arg, struct tcp_pcb *pcb, err_t err),客户端申请连接pcb = NULL,也就是说没有空余的pcb给重连客户端使用,直接仿真tcp_active_pcbs信息发现,pcb->state = FIN_WAIT_1 || FIN_WAIT_2。网线不断断开,pcb关闭4次握手没有实现,只进行一部分,一直等待中。
更改lwip源码不知重哪里下手,也怕改错出现更多bug,只能取巧弄下。
在err_t tcp_server_accept(void *arg, struct tcp_pcb *pcb, err_t err)函数最前面加个判断,客户端连接分配的pcb为空闲(全被占用了),找到等待关闭pcb全释放了(可能会出现其他问题,不过我这只是单对单使用,能重连上就行)。
if(pcb == NULL){
/*网络不稳(不断插拔网线),强制释放pcb*/
tcp_find_waitPcb();
printf("MBtcp: accept pcb == NULL\r\n");
return ERR_ARG;
}
tcp_find_waitPcb()的函数定义:
void tcp_find_distant(void)
{
struct tcp_pcb *pcb = NULL;
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next)
{
if(pcb->state == FIN_WAIT_1 || pcb->state == FIN_WAIT_2){
tcp_abort( pcb );
}
}
}
3.网线稳定,但是客户端不断快速断开连接,出现pcb = pcb->next,进入void tcp_slowtmr(void)函数死循环中出不来了。
参照:http://www.51hei.com/bbs/dpj-140158-1.html 完美解决问题
需改内容 |
解释
| |
文件名称
|
添加内容(增加红色字体)
| |
tcp.h
|
/* the TCP protocol control block */
struct tcp_pcb {
..............................略......................................
u8_t pcb_used;
};
|
在struct tcp_pcb 结构体中增加一个字段,pcb_used。这个字段值 = 0 或 = 1。
0代表这个TCP_PCB块没有在使用,已经释放。
1代表这个TCP_PCB块正在使用,占用内存。
|
memp.c
|
void memp_free(memp_t type, void *mem)
{struct memp *memp;
struct tcp_pcb *pcb;
if(type == MEMP_TCP_PCB ){
pcb = (struct tcp_pcb *)mem;
if(pcb->pcb_used == 0){
return;
}
pcb->pcb_used = 0;
}
SYS_ARCH_DECL_PROTECT(old_level);
............................略......................................
}
|
在释放TCP_PCB块的时候,如果pcb_used==0,那么这个TCP_PCB块已经释放过了,可能是没连接的块系统自己释放,也能是自己误操作,多次释放。总之,不管什么原因,已经释放过的不能再释放了,所有这边直接return退出。没有释放的正常释放,只是字段pcb_used置0。
|
tcp.c
|
struct tcp_pcb * tcp_alloc(u8_t prio)
{ ....................略.....................................
if (pcb != NULL) {
......................略......................................
pcb->pcb_used = 1;
}
return pcb;
}
|