2009-10-02 18 views
14

私の操作(読み取り/書き込み)を実現する前に、接続の状態を確認したい。boost :: asio :: ip :: tcp :: socketが接続されていますか?

isConnect()メソッドを作成する方法はありますか?

私はthisを見ましたが、「醜い」と思われます。

私もis_open()の機能をテストしましたが、期待される動作はありません。

+0

[ソケットがBoost.Asioで閉じられているかどうかをチェックする方法](http://stackoverflow.com/questions/818665/how-to-check-if-socket-is-closed-in-boost) -asio) – joshperry

答えて

28

TCPが堅牢であることを意味します厳しいネットワークに直面している。 TCPは永続的なエンドツーエンド接続のように見えますが、それはまったく嘘です。各パケットは本当にユニークで信頼できないデータグラムです。

接続は実際には、接続の各端(ソースと宛先のポートとアドレス、ローカルソケット)で追跡された小さな状態で作成された仮想コンジットです。ネットワークスタックは、この状態を使用して、各着信パケットにどのプロセスを割り当てるか、各発信パケットのヘッダーにどの状態を入れるかを知る。そのため、ネットワークの基礎となる—本質的にコネクションレスと信頼性の低い—自然の

Virtual TCP Conduit

リモートエンドが接続を閉じるにはFINパケットを送信した場合、スタックは、切断、接続を報告します、あるいは「それはdoesnの場合送信されたパケットに対するACK応答を受信しません(タイムアウトとカップル再試行後)。

asioの非同期性のため、正常に切断されたことを通知する最も簡単な方法は、接続が閉じられるとすぐにerror::eofを返す未解決のasync_readを持つことです。しかし、これだけでも、半開きの接続やネットワークの問題など、他の問題の可能性が残されています。

予期しない接続中断を回避する最も効果的な方法は、何らかのキープアライブまたはpingを使用することです。接続を介してデータを転送するこのような試みによって、意図しない切断が検出された場合に便利です。

実際にTCPプロトコルには、asio::tcp::socket::keep_aliveを使用してasioで設定できるkeep-alive mechanismが組み込まれています。キープアライブのTCPの良い点は、ユーザーモードのアプリケーションに対して透過的で、キープアライブに関心のある同輩だけがそれを設定する必要があることです。欠点は、タイムアウトパラメータを設定するためにOSレベルのアクセス/知識が必要であり、残念ながら単純なソケットオプションで公開されず、通常はかなり長いデフォルトタイムアウト値(Linuxでは7200秒)があることです。

キープアライブの最も一般的な方法は、アプリケーションが特別なnoopまたはpingメッセージを持ち、ティックルしたときに何も応答しないアプリケーション層で実装することです。この方法を使用すると、キープアライブ戦略を実装する際に最も柔軟に対応できます。

+0

キープアライブaproachには1つの問題があります。アプリケーションが実行されるサーバーにアクセスできないため、キープアライブタイムアウト(ここでは7200秒)を変更できません。しかし、私はこの応答が気に入っているので、私がこれをもう一度必要とするなら、私はTCPキール・アライブを有効にします。ありがとうございます – coelhudo

+0

私は何をしたのか忘れてしまいました。私は読み書きを試み、エラーをチェックし、このエラーに基づいて決定します。 – coelhudo

+0

イメージは表示されなくなりました。この問題を解決できますか?私はイラストを見たいと思います。ありがとう。 – coelhudo

0

ソケットにダミーバイトを送信し、エラーが返されるかどうかを確認できます。

+3

しかし、あなたが接続されている場合、このダミーバイトを受け取ったとき、相手側にはどうなりますか?それは良い解決策ではありません。 – jmucchiello

+2

通常、この種のアプリケーションには定期的に送信するハートビートの概念があります。さらに、Windows(win32)では接続を確実に確認する方法がなく、boost :: asio :: ip :: tcp :: socketが実装されています。 @jmucchiello - 分散システムで作業したことがあるなら、通常はハートビート(通常は1バイト)で接続がチェックされていることがわかります。これがOPに役立つことを願っています。 – vehomzzz

+0

1つの問題があります。私はサーバー側の動作を知らない。 私が見つけた解決策は、操作の前にconnect connectとエラー状態を確認することです。 – coelhudo

1

TCPは、確実に信頼できる接続を提供するために、ドロップされたパケットを監視することを約束します。もちろん、TCPはサーバがクラッシュしたり、イーサネットケーブルが抜けたり、同様の事態が発生した場合は処理できません。さらに、TCP接続が確立していることを知っていても、必ずしもTCP接続を経由するプロトコルが準備できているわけではありません(たとえば、HTTP WebサーバーまたはFTPサーバーが何らかの状態になっている可能性があります)。

あなたはTCPを介して送信されるプロトコルを知っているならば、物事は良い形になっているかどうかを伝えるためにそのプロトコルでの方法はおそらくあり(HTTPのはHEAD requestだろう)

関連する問題