据我所知,对于TCP套接字,ECONNRESET与RST数据包有关。但是我在read()和write()调用上也看到了AF_LOCAL套接字的ECONNRESET错误。这是什么意思? ECONNRESET与read()返回0或write()抛出EPIPE有什么不同?
答案 0 :(得分:81)
ECONNRESET似乎意味着另一方已关闭连接而没有读取已发送给它的未完成数据,并且可以在read()和write()上触发。但确切的行为取决于操作系统。
当一个write()s到一个已经关闭的套接字,并且没有未完成的传出数据时,似乎会被触发。适用于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。
请参阅特定操作系统行为的示例。如果您知道其他操作系统的行为,请提供帮助。
示例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