web-dev-qa-db-fra.com

Que signifie ECONNRESET dans le contexte d'une socket AF_LOCAL?

Je comprends que pour les sockets TCP ECONNRESET a quelque chose à voir avec les paquets RST. Mais j'ai également vu des erreurs ECONNRESET pour les sockets AF_LOCAL, sur les appels read () et write (). Qu'est-ce que cela En quoi ECONNRESET est différent de read () retournant 0 ou write () lançant EPIPE?

27
Hongli

Il semblerait que ECONNRESET signifie que l'autre côté a fermé la connexion sans lire les données en attente qui lui ont été envoyées et peut être déclenché à la fois en lecture () et en écriture (). Mais le comportement exact dépend du système d'exploitation.

EPIPE

Semble être déclenché lorsque l'on écrit () sur un socket qui a déjà été fermé et qu'il n'y a pas de données sortantes en attente. Applicable à la fois aux sockets PF_LOCAL et TCP. Exemple (Ruby):

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

read () retournant 0

Déclenché lorsque l'autre côté a fermé la connexion et qu'aucune donnée sortante n'est en attente. Applicable à la fois aux sockets PF_LOCAL et TCP.

a, b = UNIXSocket.pair
b.close
a.read    # => 0 bytes, on all OSes

ECONNRESET

Sous Linux, il se comporte comme ceci:

Déclenché lorsqu'il y a des données sortantes en attente qui n'ont pas encore été écrites de l'autre côté. read () le déclenche pour les sockets PF_LOCAL et TCP, mais write () le déclenche uniquement pour les sockets TCP; les sockets PF_LOCAL déclenchent EPIPE).

Voir des exemples de comportement de système d'exploitation spécifique. Veuillez contribuer si vous savez comment les autres systèmes d'exploitation se comportent.

Exemple 1: read () sur le socket PF_LOCAL

a, b = UNIXSocket.pair
a.write("hello")
b.close
a.read
# Linux: ECONNRESET
# OS X : returns 0 bytes

Exemple 2: read () sur TCP socket

# 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

Exemple 3: write () sur le socket 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

Exemple 4: write () on TCP socket

# 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
83
Hongli