2016-04-29 22 views
1

私はPython3/asyncio(Protocol)で書かれた私のサーバアプリケーションに問題がありますが、別のバージョンを試したのでpythonやasyncioにあまり関係ないと確信していますいくつかの5ライナーは、ソケットインターフェイスとちょうど。 多くのクライアントハードウェアTCP/IP < - > RS232コンバーターとの同時通信です。これは、書き込みをブロックするスレッドではなく、asyncioが使用される理由です。Python:TCPの壊れたルートが痛いほど検出が遅い

定期的な短いデータ送信があります。

asyncio - Fatal read error on socket transport protocol 
<_SelectorSocketTransport fd=11 read=polling write=<idle, bufsize=0>> 
Traceback (most recent call last): 
File "/usr/lib/python3.5/asyncio/selector_events.py", line 663, in 
_read_ready 
data = self._sock.recv(self.max_size) 
OSError: [Errno 113] No route to host 

それが起こる、私は15分のためのシグナリングいますを意味している「すべては大丈夫ですが、それはにISN、しかし15分後:私は物理的に接続を切断して、例外が発生するのを待つときに問題が発生しますそれは耐え難いほど長く、機能が壊れている。 動作は、Ubuntu 16.04、Ubuntu 14.04、Debian Jessieで、すべて異なるHWでチェックされています。

(おそらく)カーネルがデータをバッファリングしていることがわかりました。なぜなら、10分後にデバイスを再接続すると、すべてのデータが一度にフラッシュされるからです。私はこれが短い切断のために良いことを理解しています、私は10秒、15秒、または1分で問題はないでしょうが、15分はあまりにも多くです。

同様の質問は私の場合は不可能なアプリケーションプロトコルを実装することによって答えられました。 私はちょっと妥当な時間に相手側がパケット(TCP ACK)を取得したことを確認したいだけです。 socket.setsockoptについてのドキュメントを慎重に読んでいますが、何も役に立たなかったまた、いくつかの回避策を実行するために送信バッファがフラッシュされたかどうかをチェックする方法を見つけられませんでした。

TCPキープアライブは、非アクティブな時間に基づいており、送信データがアクティビティであるため、いずれかを助けていません。

答えて

0

TCPの再送信タイムアウト(RTO)動作が表示されます。

あなたのTCPはフィードバックを受け取りません.1それで、セグメントを取得するのは本当に難しいです。 Linuxではこの動作はnet.ipv4.tcp_retries2 = 15に支配されています

この値は、RTO 再送が未確認のまま生きているTCPコネクションのタイムアウトに影響を与えます。 Nの値が与えられると、のTCP_RTO_MINの指数バックオフに続く 仮想TCP接続は、N + 1番目のRTOで 接続を強制終了する前にN回再送します。

デフォルト値の15は、仮想タイムアウトが924.6秒であり、 であり、有効なタイムアウトの下限値です。 TCPは効果的に が仮想タイムアウトを超える最初のRTOでタイムアウトします。

これが意味することは、あなたのsendは明らかに動作します(つまりTCPは、最終的にをあなたのデータを送信することに同意した)とあなたが再試行を保つためにTCPを待つ〜900秒のことです。

アプリケーションプロトコルを変更することはこれを修正する堅牢な方法ですが、それはあなたのためには機能しないと言われているので、あなたのオプションはTCPの問い合わせを中心に行われます。

TCP_USER_TIMEOUTは正確に何をしたいやっているようだ:値が0よりも大きい場合

は、それは、データを送信するミリ秒単位で 時間の最大量は、TCPの前に 未確認残ることを指定します強制的に対応する接続​​を閉じて、 ETIMEDOUTをアプリケーションに返します。

詳細はApplication Control of TCP retransmissionを参照してください。

はまた、どのように送信バッファが 壊れたルートのいくつかの回避策 - 手動検出を行うことがフラッシュされたかどうかを確認するための方法を見つけることができませんでした。

上記の質問には、SIOCOUTQがあります(出力キューのデータ量を確認してください)。


1たとえば、TCP RSTまたはICMP到達不能を受信する可能性があります。

関連する問題