LWIP应用笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaozhiyuan111/article/details/82216563

死机现象:
设备作为客户端在判断服务器掉线重连过程中会进入lwip中两个定时器相关函数(tcp_fasttmr()和 tcp_tmr())造成死循环

LWIP_TCP修改笔记:
1.tcp_fasttmr()和 tcp_tmr()
2.回调函数Tcp_Recv中的pbuf_free(p)位置;
3.协议栈内核参数配置文件:lwipopts_.h(lwiplib_1.4.1.c -> tcp.c -> lwip/opt.h -> lwipopts_.h)
4.网卡驱动配置文件
5.系统引入sys_check_timeouts处理内核各种定时事件,则需修改系统时钟 sys_now( )函数来返回当前系统时间。
6.协议栈初始化时的g_ui32LocalTimer系统时间变量
7.应用层CreatTaskLwipTcp函数中的Task.period.tTimer时间
8.内存池memp.c文件中memp_malloc()函数与memp_free()函数
详见:https://www.amobbs.com/thread-5554416-1-1.html
9.发现客户端会不断进入CLOSE_WAIT状态(客户端不会出现CLOSE_WAIT状态,只有服务端才会出现),而客户端连接断开的整个过程应该为:
CLOSE — SYN_SENT — ESTABLISHED //// FIN_WAIT_1 — FIN_WAIT_2 — TIME_WAIT(2MSL) — CLOSE
发现问题是客户端与服务器端同时发送FIN报文所致

问题转化为:两端同时发起主动关闭时(此时没有将任何一端称为客户端或服务端),为什么设备(客户端)会进入CLOSE_WAIT状态然后造成死循环
双方同时关闭:FIN_WAIT_1 — CLOSING — TIME_WAIT —CLOSE

10.首先Client程序处于CLOSE_WAIT状态的话,说明套接字是被动关闭的!
重点: 客户端close_wait解决办法:
https://www.cnblogs.com/zl1991/p/7121736.html?utm_source=itdadao&utm_medium=referral
https://blog.csdn.net/fenglibing/article/details/36706965
https://blog.csdn.net/Poisx/article/details/79319386
http://new-restart.iteye.com/blog/1935282
因为如果是Server端主动断掉当前连接的话,那么双方关闭这个TCP连接共需要四个packet:
Server —> FIN —> Client
Server <— ACK <— Client

这时候Server端处于FIN_WAIT_2状态;而我们的程序处于CLOSE_WAIT状态(异常)。
Server <— FIN <— Client

这时Client发送FIN给Server,Client就置为LAST_ACK状态。
Server —> ACK —> Client
11.Create_LwipTcp –> u_sTcp_pcb[i]->local_port = pConnectMesg->wSrcPort;
12.tcp_bind()函数返回ERR_USE表示端口号被占用。
修改:tcp.c中tcp_close_shutdown(); pcb->local_port = 0;
资料:https://blog.csdn.net/fern_girl/article/details/73657825
http://blog.sina.com.cn/s/blog_72d911930102wnfe.html
https://blog.csdn.net/jiangjunjie_2005/article/details/26051399
13.tcp_close Lwip_TcpClose



总结:
Client产生CLOSE_WAIT状态,属于被动关闭,在被动关闭连接的情况下,在已经接收到FIN但是没有发出自己的FIN的时刻,连接会处于CLOSE_WAIT
状态(本应该持续时间很短),这是因为服务端发送的FIN包客户端接收出错,由TCP代回了一个ACK包,所以客户端就会处在CLOSE_WAIT的状态中,造成连接池的中创建连接数已经达到了最大数字,不能够创建新的连接了,已经创建的连接都是在等待关闭(CLOSE_WAIT)的状态,没有被放回到可用的连接池中,不能够用于处理新的连接请求,因而所有的请求都是堵在了从连接池中获取连接哪里。
解决办法:
检测到sever关闭后,Client自己再次主动关闭

猜你喜欢

转载自blog.csdn.net/zhaozhiyuan111/article/details/82216563
今日推荐