5

私は、TCPソケットを介して両側が通信するクライアントサーバーアプリケーションを持っています。

接続を適切に確立し、クライアントによってソケットにデータが書き込まれる前にサーバーをクラッシュさせます。
私が見ているのは、最初のwrite()試行 (クライアント側) が成功し、実際に書き込まれたバイト数が返されるのに対して、次の試行では (期待どおり) -1(a を受け取るSIGPIPE) とerrno=EPIPE.

write()ソケットが既に閉じられている場合でも、最初の方法が成功するのはなぜですか?

EDITwrite()すべてがうまくいっているかのように、次のものが正の戻り値を持つ こともあります。

4

3 に答える 3

8

の戻り値が何をwrite()意味するのか混乱しています。「ピアがデータを取得し、それを確認した」という意味ではありません。代わりに、「ピアに送信するために非常に多くのバイトをバッファリングしましたが、今は私の責任なので、忘れてください (保留中のエラーはありません)」という意味です。

つまり、TCP スタックが書き込みを受け入れてnバイトを返した場合、それはそれらがまだ書き込まれていないことを意味するのではなく、書き込みのためにキューに入れられただけです。ネットワーク トラフィックの送信を開始してから、スタックがあきらめてエラーを返すまでに、おそらく 30 秒ほど時間がかかります。その間、write()送信するデータをキューに入れることに成功したいくつかの呼び出しを行うことができました。(書き込みエラーは、ピアが消失した場合は c.30 秒で返されます。ピアに接続でき、接続が切断されたことを示すためにすぐに RST パケットを送信した場合は、すぐに返されます。)

于 2013-03-14T10:32:15.880 に答える
3

これは、TCP/IP がどのように機能するかに関係しており、2 つのほぼ独立した半接続として大まかに説明できます。サーバーでソケットを閉じると、クライアントはC<-Sハーフ接続からそれ以上データを受信しないことが通知され、read()すぐにウェイクアップしますが、C->S方向については通知されません。データを送信しようとした後、接続をリセットする応答のみを取得します。詳細については、 TCP/IP ガイドをお勧めします。

時々 2 回できる理由write()は、往復時間よりも速く書き込みwrite()、最初の応答の前に 1 秒を圧迫できるためです。

于 2013-03-14T10:12:04.140 に答える