5

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 を送信しなくなり、未処理のバイトを読み取る機会が得られるはずです。

4

2 に答える 2

1

私自身の質問に対する決定的な答えを見つけました:

「... RST セグメントを受信すると、受信側はすぐに接続を中止します。このステートメントは、この接続との間でこれ以上データを送受信できないことを意味するだけではありません。また、次のことも意味します。 TCP 受信バッファに残っている未読のデータは失われます...」という書籍「TCP/IP インターネットワーキング 第 2 巻」を引用しています。私はその本を持っていないので、彼の言葉を信じるしかない. Linuxではデータを破棄しないようで、Windowsのみ...

オリヴィエ・ラングロワのブログ

于 2012-11-24T22:45:56.543 に答える
1

SO_LINGER をいじってリセットを強制すると、保留中のデータがすべて失われるという副作用があります。あなたがそれを受け取っていないという事実は、サーバーチームがこれを行うのが間違っているというあなたが必要とするすべての証拠です.

以下に引用されている RFC 793 は、「このコマンド [ABORT] により、保留中のすべての SEND と RECEIVE が中止され、...そして特別な RESET メッセージが接続の反対側の TCP に送信される」と述べています。WR Stevens 著、TCP/IP イラストレイテッド、 Vol. 1、p。287: '接続を中止すると、アプリケーションに次の 2 つの機能が提供されます。(1) キューに入れられたデータはすべて破棄され、リセットがすぐに送信されます。(2) RST の受信者は、相手側が接続の代わりに中止を行ったことを通知できます。ノーマルクローズ」。同様の文言が、それを実装する BSD コードからの抜粋とともに、Vol. 2.

TIME_WAIT 状態は、FIN を受信する前に FIN を送信するソケットでのみ発生します。RFC 793を参照してください。したがって、サーバーは、リセットするのではなく、適切なタイムアウトでクライアントからの FIN を待機する必要があります。これにより、クライアントが接続プーリングを行うことも許可されます。

于 2012-11-24T18:28:24.810 に答える