ECONNRESET在AF_LOCAL套接字的上下文中意味着什么?

Hon*_*gli 27 sockets posix

据我所知,对于TCP套接字,ECONNRESET与RST数据包有关.但是我在read()和write()调用上也看到了AF_LOCAL套接字的ECONNRESET错误.这是什么意思?ECONNRESET与read()返回0或write()抛出EPIPE有什么不同?

Hon*_*gli 83

似乎ECONNRESET意味着另一方已关闭连接而没有读取已发送给它的未完成数据,并且可以在read()和write()上触发.但确切的行为取决于操作系统.

EPIPE

当一个write()s到一个已经关闭的套接字,并且没有未完成的传出数据时,似乎会被触发.适用于PF_LOCAL和TCP套接字.示例(Ruby):

a, b = UNIXSocket.pair
b.close
a.write("foo")   # => EPIPE, on all OSes
Run Code Online (Sandbox Code Playgroud)

read()返回0

当另一侧关闭连接时触发,并且没有未完成的传出数据.适用于PF_LOCAL和TCP套接字.

a, b = UNIXSocket.pair
b.close
a.read    # => 0 bytes, on all OSes
Run Code Online (Sandbox Code Playgroud)

ECONNRESET

在Linux上它的行为如下:

当尚未写入另一方的未完成的传出数据时触发.read()为PF_LOCAL和TCP套接字触发它,但write()仅为TCP套接字触发它; PF_LOCAL套接字触发EPIPE.

查看特定操作系统行为的示例.如果您知道其他操作系统的行为,请提供帮助.

示例1:PF_LOCAL套接字上的read()

a, b = UNIXSocket.pair
a.write("hello")
b.close
a.read
# Linux: ECONNRESET
# OS X : returns 0 bytes
Run Code Online (Sandbox Code Playgroud)

示例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
Run Code Online (Sandbox Code Playgroud)

示例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
Run Code Online (Sandbox Code Playgroud)

示例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
Run Code Online (Sandbox Code Playgroud)