web-dev-qa-db-ja.com

AF_LOCALソケットのコンテキストでECONNRESETは何を意味しますか?

TCPソケットの場合ECONNRESETがRSTパケットと何らかの関係があることを理解しています。しかし、AF_LOCALソケットでも、read()およびwrite()呼び出しでECONNRESETエラーが発生しました。これは何をするのですか? ECONNRESETは、read()が0を返す、またはwrite()がEPIPEをスローするのとどう違うのですか?

27
Hongli

ECONNRESETは、送信された未処理のデータを読み取らずに相手側が接続を閉じたことを意味し、read()とwrite()の両方でトリガーできるようです。ただし、正確な動作はオペレーティングシステムによって異なります。

EPIPE

すでに閉じられているソケットに対して1つのwrite()が行われ、未処理の送信データがない場合にトリガーされるようです。 PF_LOCALとTCPソケットの両方に適用できます。例(Ruby):

a, b = UNIXSocket.pair
b.close
a.write("foo")   # => EPIPE, on all OSes

read()は0を返します

反対側が接続を閉じ、未処理の送信データがない場合にトリガーされます。 PF_LOCALとTCPソケットの両方に適用できます。

a, b = UNIXSocket.pair
b.close
a.read    # => 0 bytes, on all OSes

ECONNRESET

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
83
Hongli