问题还原:
正常工作情况下,拔掉网上超过6秒会出现网络故障,通信一直失败,必须重启单片机。
原因分析:
通过上位机ping仍然正常。通过keil调试发现TCP仍然处于连接状态,但tcp协议不回应。说明:网络连接正常,但端口通信有问题,可能是端口在断线后相关资源并未释放。客户端重连服务端,TCP网线热插拔故障,客户端端口会一直改变。
在线调试:
debug过程中在TCP接收线程中故障状态下断点并不执行到,但TCP连接线程正常执行且只执行到connect,但状态寄存器读出数据一直是0x00ffff。所以无法按照一般的解决方案,通过连接状态判定处理。只能从接收超时来判断并释放之前绑定的资源。
客户端重连服务端,写个小程序,显示IP和端口号,如图,发现端口号每次连接都是随机的。
查看此文很清晰:
硬件平台描述:
stm32F407+DM9162做tcp服务器端,上位机作客户端,通信协议为MODBUS TCP
问题还原:
正常工作情况下,拔掉网上超过6秒会出现网络故障,modbus通信一直失败,必须重启单片 机。
原因分析:
通过上位机ping仍然正常。使用Wireshark抓包发现TCP仍然处于连接状态,但modbus tcp协议不回应。说明:网络连接正常,但502端口通信有问题,可能是端口在断线后相关资源并未释放。
在线调试:
debug过程中在“tcp_server_thread”线程中故障状态下断点并不执行到,但“ethernetif_set_link”线程正常执行,但状态寄存器读出数据一直是0x00ffff。所以无法按照一般的解决方案,通过连接状态判定处理。只能从接收超时来判断并释放之前绑定的资源。
具体实施:
查看netconn结构体发现接收超时recv_timeout属于未定义状态,改变定义声明。
结果:
烧写程序后,重复网线热插拔,间隔10s,通信恢复正常。但在cubemx重新初始化后发现接收超时重新定义为0。
仔细查看才发现有高级参数设置,如下图:
设置完成后,网线热插拔问题解决!
————————————————
版权声明:本文为CSDN博主「Coverera」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Coverera/article/details/120985676
TCP连接不上的一篇文章:
前段时间业务团队在使用某平台中转服务的时候,偶尔出现connect失败的情况。这里简单总结下connect失败的可能原因,供参考。
一。网络不通
由于iptables防火墙隔离等原因,导致两台机器之间无法连接。
二。网络波动
偶尔出现的网络故障,导致两台机器之间连接失败。一般可以通过ping找到蛛丝马迹
三。client端分配不到“端口”
可能的原因有2个:
1.内核端口区间配置的太小。比如:
$ cat /proc/sys/net/ipv4/ip_local_port_range
32768 40000
可以调整成1024 65535, 注意1024以下是高危端口,不要使用
开启快速回收:
echo 1 >/proc/sys/net/ipv4/tcp_tw_recycle # 开启快速回收
echo 1 >/proc/sys/net/ipv4/tcp_tw_reuse # 开启重用
四。server端的连接队列配置的过小
1.server端接受syn包的队列太小。比如:
$ cat /proc/sys/net/ipv4/tcp_max_syn_backlog
1024
可以适当调大,比如调整到4096
2.server端socket listen backlog太小。
2.1 内核参数somaxconn太小, 比如:
$ cat /proc/sys/net/core/somaxconn
128
可以适当调大,比如调整到1024
2.2 代码中listen(int sockfd, int backlog)的backlog太小, 适当调大, 比如调整到1024
五。server繁忙、处理能力太弱
由于server过渡繁忙,或者server处理非常耗时,导致不能即时的accept客户端的连接。如果是进程数太少则调大进程数, 否则可能需要扩容
————————————————
版权声明:本文为CSDN博主「brk」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/nullzhou/article/details/38703467