TCPソケットの場合ECONNRESETがRSTパケットと何らかの関係があることを理解しています。しかし、AF_LOCALソケットでも、read()およびwrite()呼び出しでECONNRESETエラーが発生しました。これは何をするのですか? ECONNRESETは、read()が0を返す、またはwrite()がEPIPEをスローするのとどう違うのですか?
ECONNRESETは、送信された未処理のデータを読み取らずに相手側が接続を閉じたことを意味し、read()とwrite()の両方でトリガーできるようです。ただし、正確な動作はオペレーティングシステムによって異なります。
すでに閉じられているソケットに対して1つのwrite()が行われ、未処理の送信データがない場合にトリガーされるようです。 PF_LOCALとTCPソケットの両方に適用できます。例(Ruby):
a, b = UNIXSocket.pair
b.close
a.write("foo") # => EPIPE, on all OSes
反対側が接続を閉じ、未処理の送信データがない場合にトリガーされます。 PF_LOCALとTCPソケットの両方に適用できます。
a, b = UNIXSocket.pair
b.close
a.read # => 0 bytes, on all OSes
Linuxでは、次のように動作します。
まだ反対側に書き込まれていない未処理の送信データがある場合にトリガーされます。 read()はPF_LOCALとTCPソケットの両方に対してトリガーしますが、write()はTCPソケットに対してのみトリガーします。PF_LOCALソケットはEPIPEをトリガーします。
特定のOSの動作の例を参照してください。他のOSの動作を知っている場合は、貢献してください。
例1:PF_LOCALソケットのread()
a, b = UNIXSocket.pair
a.write("hello")
b.close
a.read
# Linux: ECONNRESET
# OS X : returns 0 bytes
例2:TCPソケットのread()
# Side A # Side B
s = TCPServer.new('127.0.0.1', 3001)
c = s.accept
c = TCPSocket.new('127.0.0.1', 3001)
c.write("hello")
c.close
c.read
# Linux: ECONNRESET
# OS X : returns 0 bytes
例3:PF_LOCALソケットでのwrite()
a, b = UNIXSocket.pair
a.write("hello")
b.close
a.write("world")
# Linux: EPIPE and not ECONNRESET
# OS X : EPIPE and not ECONNRESET
例4:TCPソケットでのwrite()
# Side A # Side B
s = TCPServer.new('127.0.0.1', 3001)
c = s.accept
c = TCPSocket.new('127.0.0.1', 3001)
c.write("hello")
c.close
c.write("world")
# Linux: ECONNRESET
# OS X : no error