Может показаться, что ECONNRESET означает, что другая сторона закрыла соединение без чтения ожидающих данных, которые были ему отправлены, и может быть запущена как read (), так и write (). Но точное поведение зависит от операционной системы.
EPIPE
Кажется, что срабатывает, когда одна запись (ы) в сокет, который уже был закрыт, и нет ожидающих исходящих данных. Применимо к сокетам 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.
См. Примеры для конкретного поведения ОС. Пожалуйста, помогите, если знаете, как ведут себя другие ОС.
Пример 1: чтение () для сокета PF_LOCAL
a, b = UNIXSocket.pair
a.write("hello")
b.close
a.read
# Linux: ECONNRESET
# OS X : returns 0 bytes
Пример 2: чтение () на сокете TCP
# 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
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-сокет
# 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