Что означает ECONNRESET в контексте сокета AF_LOCAL?

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

1 ответ

Решение

Похоже, что ECONNRESET означает, что другая сторона закрыла соединение без чтения ожидающих данных, которые были ему отправлены, и может быть запущена как read (), так и write (). Но точное поведение зависит от операционной системы.

EPIPE

Кажется, срабатывает, когда один write () s в сокет, который уже был закрыт, и нет ожидающих исходящих данных. Применимо к сокетам PF_LOCAL и TCP. Пример (Ruby):

a, b = UNIXSocket.pair
b.close
a.write("foo")   # => EPIPE, on all OSes

читать () возвращая 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
Другие вопросы по тегам