Python Modbus TCP客户端关闭连接,因为我的服务器实现出现意外响应
我用Python实现了一个基于TCP的Modbus作为服务器软件。应用程序是多线程的,并且严重依赖于标准libs。我在管理服务器端的连接时遇到问题。 同时,我作为Modbus over TCP作为客户端的实现工作得很好 实现描述Python Modbus TCP客户端关闭连接,因为我的服务器实现出现意外响应,python,tcp,modbus,Python,Tcp,Modbus,我用Python实现了一个基于TCP的Modbus作为服务器软件。应用程序是多线程的,并且严重依赖于标准libs。我在管理服务器端的连接时遇到问题。 同时,我作为Modbus over TCP作为客户端的实现工作得很好 实现描述 服务器是多线程的,一个线程管理SOCK_流套接字以接收数据 框架 出于效率原因,使用select 信号量用于在发送或接收时防止对套接字资源的并发访问 Modbus上层的封装是通过发送和接收方法透明地完成的,不管怎样,只需构建一个具有正确标头和有效负载的帧 另一个线程运
- 服务器是多线程的,一个线程管理SOCK_流套接字以接收数据 框架
- 出于效率原因,使用select
- 信号量用于在发送或接收时防止对套接字资源的并发访问
- Modbus上层的封装是通过发送和接收方法透明地完成的,不管怎样,只需构建一个具有正确标头和有效负载的帧
- 另一个线程运行,在它内部调用Modbus发送和接收方法李>
- 客户:SYN
- 我的应用服务器:SYN,ACK
- 客户:ACK
- 客户端:发送Modbus帧,TCP标志=0x18,即确认+推送
- 我的应用服务器:不等待并发送单个空TCP确认帧
- 客户端:等待带有tcp ack标志的modbus帧。因此,将其视为错误并要求关闭连接
- 我收到主线程需要处理的modbus帧(服务器端)
- 处理需要几毫秒,同时通过我的服务器套接字发送一个TCP ACK帧,而我希望它不发送任何东西李>
我希望我足够清楚。所有TCP数据包都必须包含有效负载,这似乎是一个奇怪的要求,因为这非常难以控制,除非您与TCP堆栈集成。如果确实是因为ACK没有Modbus有效负载而导致客户端崩溃,我认为您可以从python中做的唯一事情就是尝试禁用TCP_QUICKACK套接字选项,以便TCP在发送ACK之前等待500毫秒。这显然不会在所有情况下都起作用(或者如果代码创建响应的时间大于500毫秒,则可能根本不起作用),但我不知道还有其他使用python中socket API的选项
此答案告诉您如何禁用它:。应该很容易找到如何从中启用它。注意,您需要在收到数据后不断地重新启用它 我不熟悉Modbus,但是如果您正在用Python编写TCP内容,发送/接收ACK对您的代码不应该是完全透明的吗?在PythonTCP客户机中,您如何知道在没有有效负载的情况下收到了ACK?recv()应该在有实际数据时返回。我不明白为什么发送一个空的ACK是不好的,并且会导致一个错误。在任何情况下,您都可以尝试使用延迟确认:TCP_QUICKACK套接字选项。您是对的,我不想直接管理TCP堆栈,我希望它对我来说是透明的。然而,我在wireshark(网络嗅探工具)上看到,我的套接字在没有有效负载的情况下自己发送TCP ACK。而我的应用程序仍然处于适当的处理过程中。发送一个空的TCP ACK似乎被Modbus客户端当作一个错误的例子,这就是为什么我会阻止底层TCP栈发送任何类型的TCP ACK,因为一些TimeSTCP ACK是TCP可靠性特征的一个组成部分。如果阻止发送,客户端网络堆栈将重新发送最后一个数据包。此外,Modbus应该位于TCP之上,这意味着它通常不知道ACK数据包之类的事情。如果客户端因为收到ACK而崩溃,则表明它做错了。感谢您的回答,不幸的是,服务器正在windows操作系统上运行。无论如何,这个参数在注册表中似乎是可调的。。。我要试一试。