我已经在 Python 中实现了一个基于 TCP 的 Modbus 作为服务器软件。应用程序是多线程的,并且严重依赖标准库。我在管理服务器端的连接时遇到问题。同时,我作为客户端的 Modbus over TCP 实现工作得很好。
实现说明
- 服务器是多线程的,一个线程管理 SOCK_STREAM 套接字用于接收帧
- 出于效率原因使用 select
- 信号量用于防止在发送或接收时对套接字资源的并发访问
- Modbus上层的封装是通过发送和接收方法透明地完成的,无论如何只是构建一个带有正确的头和有效载荷的帧......
- 另一个线程运行,在其中调用 Modbus 发送和接收方法。
TCP 上下文
TCP 启动并运行,绑定到一个端口,最大客户端设置和侦听。
wireshark 下的痕迹显示:
- 客户:SYN
- 我的应用服务器:SYN、ACK
- 客户:ACK
在服务器端,一个全新的套接字已按预期创建并绑定到客户端套接字。
到目前为止,一切都很好。
Modbus 上下文
- 客户端:发送 Modbus 帧,TCP 标志 = 0x18,即 ACK + PUSH
- 我的应用服务器:不等待并发送一个空 TCP 确认帧。
- 客户端:等待带有 tcp ack 标志的 modbus 帧。因此,将其视为错误并要求关闭连接。
因此,我的服务器软件之后无法发送任何实际响应,因为客户端的套接字正在关闭或已经关闭。
我的问题
- 我收到一个主线程需要处理的 modbus 帧(服务器端)
- 处理需要几毫秒,同时通过我的服务器套接字发送一个 TCP ACK 帧,而我希望它不发送任何东西!
您对如何管理 ACK 行为有任何想法吗?我已经阅读了有关 naggle 算法的内容,但它似乎不在问题的范围内……我不确定 setsockopt 方法的任何选项也能解决我的问题,但我可能弄错了。
如果您有任何建议,我很感兴趣......我希望我足够清楚。