私は、単一のクライアントが単一のサーバと通信するアプリケーションを持っています。通常、クライアントは単一のconnect
を実行し、次にsend
を繰り返し呼び出しますが、問題はありません。TCPソケット接続がSO_REUSEADDRで信頼できなくなる
しかし、私は、クライアントがsend
(HTTPのように、keep-alive
の有無のようなビット)ごとに接続を設定するバージョンを行う必要があります。このバージョンでは、クライアントはsocket
,connect
、send
を一度呼び出してからclose
を呼び出します。
この問題は、一時的なクライアントポートが非常にすぐに使い果たされ、connect
が失敗するという問題があります。これを回避するために、connect
(たとえば、hereを参照)を呼び出す前に、setsockopt
をSO_REUSEADDR
と呼び出してから、ポート0にバインドします。
TCP接続が信頼できなくなることを除いて、これは機能します。おそらく、TCP接続が閉じられたときにデータが残っているため、間違ったデータが表示されることがあります。
これを信頼性高く(高速に)する方法はありますか? shutdown
の前にclose
は役に立ちません。たぶん私はselect
ソケットが出力の準備ができている場合私に教えてもらうことができますが、それは過度のように思えます。
どのくらいの頻度で 'send'を呼び出しますか? TCPは実際には 'connect' - ' send' - 'close'繰り返しサイクルのために設計されていません。これは、TCPのセットアップとティアダウンが高価になる可能性があるためです。おそらく、あなたがなぜこれを必要としているのか理由を*私たちに教えてもらえますか?なぜ 'connect' - ' send' - 'send' -----' close'を使うことができませんか?代わりに、未接続のUDPの使用を検討するべきでしょうか? –
エンドアプリケーションは時々、高頻度のパケットのバーストを送信しますが、送信間ではるかに長く待つこともできます。これは時折失敗し、書き直されています(boost :: asioからplain-old-Cへ)。現在のコードは何が可能かを調べるためのテストです。もし私が一度 'connect'してコネクションを開いたままにしておけば、私はそれをしますが、それが唯一または最良のオプションであることを確認したいと思います。 'connect'-' send'-'close'は、エラーリカバリの観点から見るときれいに感じるかもしれません。か否か。 – EML
TCPは*信頼できる*プロトコルであることに注意してください。エラーが発生した場合は、送信または受信通話でその旨が通知され、その時点で(接続を切断して再試行して)エラー回復を行います。私が言ったように、TCPの接続設定と解体は高価です。古いHTTPは、この点でTCPの使い方に関する悪い例です。 –