2012-04-05 30 views
2

asioを使用する非同期TCP/IPクライアントがあります。接続が失われたとき、async_readの私のハンドル関数はエラーを受け取ります。だから私は接続が失われたことを知らされています。boost asio:tcp接続がアクティブであることを監視する方法

ここでは、同期型TCP/IPクライアントを実装するいくつかのレガシーコードをリファクタリングしています。抽象的なインターフェイスでこのシーケンスが適用されます。同期書き込み、同期読み取りです。 asioでそれを行うことはかなり簡単ですが、接続が失われた場合は非同期的に知りたいと思います。

よりエレガントな方法があります:

オプションA: を読み取ろうとすることによって(ソケットがまだ生きているかどうかを確認するスレッドを追加...しかし、どのように私は読むことを確認することができますが、私の同期リードからデータを盗むしないBoost asio ip tcp iostream Error Detectionを参照してください)

オプションB:? 利用代わりasync_readと、同期をエミュレートし、私はシンという想像

+0

私は答えがノーだと思います。たぶんいくつかのプラットフォーム固有のソリューションがあります。 – mirk

+0

私は、TCPプロトコルが特定の時間枠内で送信されたパケットへの肯定応答を受信しない限り、接続障害を検出できないと思います。 – Ferruccio

+0

私はオプションBを実装しました。しかし、理解できない2つのことがあります。1.切断は検出されません。2.サーバー(プリンタ)のイーサネットケーブルを外しても、エラーは返されません。 2回目だけ、エラーを投げます – DoogQc

答えて

2

を読みます非同期オペレーションと同じように、時系列オペレーションは失敗します。タイムアウトが非常に長くなる可能性があり、他のすべてがそれを待たなければならないときに、はるかに目立つので、同期が失敗したときにはより破壊的になるかもしれません。

ソケットでTCPキープアライブを有効にし、TCPキープアライブ間隔を短くして、失われた接続を早期に検出することができます。

+0

値する言及; TCPキープアライブにはいくつかの制限があります。特に、キープアライブのタイムアウトを設定する移植性のある方法はありません。また、デフォルトのタイムアウトはかなり大きいです。たとえば、Linuxでは、デフォルトのキープアライブ間隔は2時間です。接続が停止する前に9プローブが失敗しなければなりません。 – Rawler

+0

ほとんどの場合、アプリケーションコード内で自分自身で接続タイムアウトを処理し、「ハートビート」を追加することが必要です。可能であればプロトコルにチェックを入れ、タイムアウトのためのデフォルト設定を試みます。 (「この操作は実際には5秒かかるはずですか?」など) – Rawler

関連する問題