我在 Modbus 主站和从站 TCP 通信方面遇到了问题,
在 Windows 计算机上:当主机和从机相互连接时,它们在 50905->502 端口上成功通信,当我断开主设备的以太网电缆并再次连接时,主设备的以太网端口更改为 50908->502(然后主设备向从机发送 ack,但从机的 tcp 连接至少处于活动状态(50905->502)并且任何人都关闭它。主 PC 无法在套接字之前关闭,因此从机设备结束了对主设备的所有新连接请求,从机尝试在连接之前关闭每个连接尝试。问题 1) 为什么在插入以太网连接时 PC 打开新的 tcp 端口?为什么在恢复连接时不从前一个端口恢复当前通信?这是正确的情况吗?问题 2) 从机应该管理端口关闭操作,还是主机应该负责?
我该如何分析我的问题并解决,请帮帮我?
编辑:
根据命令:我更改以下值:
/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */
#ifndef TCP_KEEPIDLE_DEFAULT
#define TCP_KEEPIDLE_DEFAULT 1000UL /* Default KEEPALIVE timer in milliseconds */
#endif
#ifndef TCP_KEEPINTVL_DEFAULT
#define TCP_KEEPINTVL_DEFAULT 1000UL /* Default Time between KEEPALIVE probes in milliseconds */
#endif
我在 lwipopth.h 中添加了以下行:
#define LWIP_TCP_KEEPALIVE 1// enable "kepp-alive"
当我拔下以太网电缆并重新连接时,我会永远收到以下数据包。我无法解决上述问题,我该如何解决这个问题? 在此处输入图片描述
1.40 => 从属,其他为主
答案1
如果一方强行关闭了连接,另一方就无法知道,因此该方使用的套接字将保持打开状态。
即使在套接字关闭之后,操作系统仍会将连接保持在不确定状态一段时间,因此将阻止针对相同的“源地址、源端口、目标地址、目标端口”四元组接受任何其他连接。
在 Windows 下,你可以通过设置来缩短连接保持的时间 TcpTimedWaitDelay。
如果代码在您的控制之下,解决方案是在程序中使用以下代码设置套接字选项: 设置sockopt 像这样:
setsockopt(socket,SOL_SOCKET,SO_REUSEADDR ... )
这个选项SO_KEEPALIVE
对于套接字定期检查另一端是否仍然连接很有用。
也可以看看这个答案关于如何设置 Windows 来定期检查所有套接字是否仍在两侧连接,我有一个建议。