2017-05-18 9 views
0

私は、単一のクライアントが単一のサーバと通信するアプリケーションを持っています。通常、クライアントは単一のconnectを実行し、次にsendを繰り返し呼び出しますが、問題はありません。TCPソケット接続がSO_REUSEADDRで信頼できなくなる

しかし、私は、クライアントがsend(HTTPのように、keep-aliveの有無のようなビット)ごとに接続を設定するバージョンを行う必要があります。このバージョンでは、クライアントはsocket,connectsendを一度呼び出してからcloseを呼び出します。

この問題は、一時的なクライアントポートが非常にすぐに使い果たされ、connectが失敗するという問題があります。これを回避するために、connect(たとえば、hereを参照)を呼び出す前に、setsockoptSO_REUSEADDRと呼び出してから、ポート0にバインドします。

TCP接続が信頼できなくなることを除いて、これは機能します。おそらく、TCP接続が閉じられたときにデータが残っているため、間違ったデータが表示されることがあります。

これを信頼性高く(高速に)する方法はありますか? shutdownの前にcloseは役に立ちません。たぶん私はselectソケットが出力の準備ができている場合私に教えてもらうことができますが、それは過度のように思えます。

+0

どのくらいの頻度で 'send'を呼び出しますか? TCPは実際には 'connect' - ' send' - 'close'繰り返しサイクルのために設計されていません。これは、TCPのセットアップとティアダウンが高価になる可能性があるためです。おそらく、あなたがなぜこれを必要としているのか理由を*私たちに教えてもらえますか?なぜ 'connect' - ' send' - 'send' -----' close'を使うことができませんか?代わりに、未接続のUDPの使用を検討するべきでしょうか? –

+0

エンドアプリケーションは時々、高頻度のパケットのバーストを送信しますが、送信間ではるかに長く待つこともできます。これは時折失敗し、書き直されています(boost :: asioからplain-old-Cへ)。現在のコードは何が可能かを調べるためのテストです。もし私が一度 'connect'してコネクションを開いたままにしておけば、私はそれをしますが、それが唯一または最良のオプションであることを確認したいと思います。 'connect'-' send'-'close'は、エラーリカバリの観点から見るときれいに感じるかもしれません。か否か。 – EML

+0

TCPは*信頼できる*プロトコルであることに注意してください。エラーが発生した場合は、送信または受信通話でその旨が通知され、その時点で(接続を切断して再試行して)エラー回復を行います。私が言ったように、TCPの接続設定と解体は高価です。古いHTTPは、この点でTCPの使い方に関する悪い例です。 –

答えて

0

TCPを使用する必要がありますか?その場合は、おそらく開いている接続を維持し、その1つの接続でメッセージをルーティングする必要があります。 TCPのよう

、SCTPは、輻輳制御と信頼性の高い、接続指向のデータ配信を提供します。信頼性の高いデータグラム・プロトコル -

ご利用の場合に適していてもよく、SCTPがあります。 SCTPは、TCPとは異なり、メッセージの境界を保護し、順序付けされたメッセージ配信と順序付けられていないメッセージ配信、マルチストリーミングとマルチホーミングを提供します。データの破損の検出、データの損失、データの複製は、チェックサムとシーケンス番号を使用して実現されます。データの紛失または破損を修正するために、選択的な再送信メカニズムが適用されます。