【发布时间】:2010-06-04 12:23:07
【问题描述】:
我知道对于 TCP 套接字,ECONNRESET 与 RST 数据包有关。但是我在 read() 和 write() 调用中也看到了 AF_LOCAL 套接字的 ECONNRESET 错误。这是什么意思? ECONNRESET 与 read() 返回 0 或 write() 抛出 EPIPE 有何不同?
【问题讨论】:
我知道对于 TCP 套接字,ECONNRESET 与 RST 数据包有关。但是我在 read() 和 write() 调用中也看到了 AF_LOCAL 套接字的 ECONNRESET 错误。这是什么意思? ECONNRESET 与 read() 返回 0 或 write() 抛出 EPIPE 有何不同?
【问题讨论】:
看起来 ECONNRESET 意味着对方已经关闭了连接而没有读取发送给它的未完成数据,并且可以在 read() 和 write() 上触发。但具体行为取决于操作系统。
似乎当一个 write()s 到一个已经关闭的套接字并且没有未完成的传出数据时触发。适用于 PF_LOCAL 和 TCP 套接字。示例(红宝石):
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
【讨论】: