6

Unix Network Programmingによると、ソケットが (FIN パケットの後) 閉じたソケットに 2 回書き込むと、最初は送信に成功しましたが、他のホストから RST パケットを受信しました。ホストは RST を受信するため、ソケットは破棄されます。したがって、2 回目の書き込みでは、SIGPIPE シグナルが受信され、EPIPE エラーが返されます。

ただし、send man ページでは、ECONNRESET が返される場合があります。これは、RST パケットが受信されたことを意味します。ECONNRESET が返されると、シグナルは返されません。

ECONNRESET が返される可能性があるのはどのような場合ですか? この場合、なぜ SIGPIPE シグナルがないのですか?

注: I similar question hereを確認しました。ただし、Linux コンピューターで実行すると、send は ECONNRESET ではなく EPIPE エラーを返しました。

4

2 に答える 2

12

ソケット バッファに未処理のデータが残っている間にピアが接続を閉じた場合、ピアは RST パケットを送り返します。これにより、フラグがソケットに設定され、次の送信で結果として ECONNRESET が返されます。未処理のデータがない状態で接続がピアによって閉じられた場合、代わりに送信時に EPIPE が返されます (または SIGPIPE がトリガーされます)。どちらの場合も、ローカル ソケットはまだ開いています (つまり、ファイル記述子は有効です) が、基になる接続は閉じられています。

例: 1 バイトを読み取ってから接続を閉じるサーバーを想像してください。

  • EPIPE: クライアントは最初の 1 バイトを送信します。サーバーがバイトを読み取って接続を閉じた後、クライアントはさらにデータを送信し、次に再びデータを送信します。最新の送信呼び出しが EPIPE/SIGPIPE をトリガーします。
  • ECONNRESET: クライアントは、最初に複数のバイトを送信します。サーバーは 1 バイトを読み取り、ソケットの受信バッファーにさらにバイトがある状態で接続を閉じます。これにより、サーバーからの接続 RST パケットがトリガーされ、次の送信時にクライアントは ECONNRESET を受信します。
于 2015-10-10T12:21:23.467 に答える