Python のサーバー ソフトウェアとして Modbus over TCP を実装しました。アプリはマルチスレッド化されており、標準ライブラリに大きく依存しています。サーバー側での接続の管理に問題があります。一方、クライアントとしての Modbus over TCP としての私の実装は問題なく動作します。
実装の説明
- サーバーはマルチスレッドで、1 つのスレッドがフレーム受信用の SOCK_STREAM ソケットを管理します。
- select は効率上の理由から使用されます
- セマフォは、送受信中にソケット リソースへの同時アクセスを防止するために使用されます。
- Modbus 上位層のカプセル化は、送信メソッドと受信メソッドを介して透過的に行われます。とにかく、正しいヘッダーとペイロードを使用してフレームを構築するだけです...
- 別のスレッドが実行され、その中で Modbus の送信および受信メソッドが呼び出されます。
TCP コンテキスト
TCP が稼働中で、ポートにバインドされ、最大クライアントが設定され、リッスンしています。
Wireshark ショーの下のトレース:
- 依頼人:シン
- 私のアプリ サーバー: SYN、ACK
- クライアント: ACK
サーバー側では、まったく新しいソケットが期待どおりに作成され、クライアント ソケットにバインドされています。
これまでのところ、すべて問題ありません。
Modbus コンテキスト
- クライアント: Modbus フレームを送信、TCP フラグ = ACK + PUSH である 0x18
- 私のアプリ サーバー:待機せず、単一の空の TCP ack フレームを送信します。
- クライアント: tcp ack フラグ付きの modbus フレームを待ちます。したがって、それをエラーと見なし、接続を閉じるように求めます。
したがって、クライアント側のソケットが閉じられているか、すでに閉じられているため、サーバーソフトウェアはその後実際の応答を送信できません。
私の問題
- メインスレッドが処理する必要のある modbus フレームを受信しました (サーバー側)
- 処理には数ミリ秒かかります。その間、TCP ACK フレームがサーバー ソケットを介して送信されますが、何も送信しないでください。
ACK 動作を管理する方法について何か考えはありますか? naggle アルゴリズムについて読んだことがありますが、ここでの問題の範囲には含まれていないようです... setsockopt メソッドのオプションが私の問題も解決するかどうかはわかりませんが、間違っている可能性があります。
何か提案があれば、私は非常に興味があります... 私が十分に明確であることを願っています.