Что означает ECONNRESET в контексте сокета AF_LOCAL? - PullRequest
27 голосов
/ 04 июня 2010

Я понимаю, что для сокетов TCP ECONNRESET как-то связан с RST-пакетами. Но я видел ошибки ECONNRESET для сокетов AF_LOCAL и при вызовах read () и write (). Что это значит? Чем ECONNRESET отличается от read (), возвращающего 0 или write (), выдающего EPIPE?

1 Ответ

82 голосов
/ 05 июня 2010

Может показаться, что 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...