C++ で書かれた、ソケットを使用するクロスプラットフォーム クライアント アプリケーションを作成しています。情報の送信が完了したときに、サーバーがソケットを強制的に閉じるという問題が発生しています。
私はこのトピックに関する他の投稿を読んでおり、このアプローチの正誤にはあまり興味がありませんが、サーバーが SO_LINGER=0 を明示的に設定しているか、それがそのシステムのデフォルトの動作であるようです (よくわかりませんが、これは Linux ボックスです)。
(Wireshark で) データが送信された後、数ミリ秒以内に RST が送信され、サーバーによる強制終了を示していることがわかります。ソケットをシャットダウンするのはクライアント次第であるため、私は個人的にこのアプローチに同意しません。
サーバー チームは、そのアプローチ (シャットダウンではなくハード クローズを行う) に何の問題もないと言っています。サーバーでは、TIMED_WAIT ソケットの蓄積を避けるのが一般的です。Windows では、select()
読み取るものがあることを示すリターンが返されます (ただし、この「転送中」のデータはまだ読み取っていません)。
ただし、RST がすぐに到着したため、Windows ではrecv()
-1 が返され、エラー コード (ピアによる接続のリセット) に 10054 が表示されます。少なくとも送信されたデータを取得できれば、これはそれほど悪くはありませんが、クライアントのソケット スタックが RST を確認すると、未読のバイトは使用できなくなったようです。
Linux (クライアント) では問題ありません。RST が受け入れられる前に未処理のバイトを読み取ることができるという点で、TCP スタックの動作が少し異なっているようです。Linuxクライアントで機能することを考えると、サーバー担当者にバグがあると納得させるのに苦労しています。
まず、私は正しいですか?これはサーバー側の問題ですか? クライアント側が何か間違ったことをしていることがわからないので、それは正しいに違いありませんか?
サーバーチームは、クローズを実行したいと断言しているようで、TIMED_WAIT を使用したくないので、2 秒などの SO_LINGER を追加するようにプッシュするつもりでしたか? それは私の問題を解決するように聞こえますか?私が理解していることから、これによりサーバーはデータを送信した直後に RST を送信しなくなり、未処理のバイトを読み取る機会が得られるはずです。