Wie behandelt der Linux-Socket POLLERR, POLLHUP und POLLNVAL?

8

Ich frage mich, was getan werden sollte, wenn die Umfrage diese Bits setzt? Close Socket, ignoriere es oder was?

    
user3790882 16.07.2014, 22:06
quelle

4 Antworten

11

A POLLHUP bedeutet, dass der Socket nicht mehr verbunden ist. In TCP bedeutet dies, dass FIN empfangen und gesendet wurde.

A POLLERR bedeutet, dass der Socket einen asynchronen Fehler erhalten hat. In TCP bedeutet dies normalerweise, dass eine RST empfangen oder gesendet wurde. Wenn der Dateideskriptor kein Socket ist, kann POLLERR bedeuten, dass das Gerät die Abfrage nicht unterstützt.

Bei beiden obigen Bedingungen ist der Socket-Dateideskriptor noch offen und wurde noch nicht geschlossen (aber shutdown() wurde möglicherweise bereits aufgerufen). Ein close() auf dem Dateideskriptor wird Ressourcen freigeben, die noch für den Socket reserviert werden. Theoretisch sollte es möglich sein, den Socket sofort wiederzuverwenden (z. B. mit einem anderen connect() -Aufruf).

A POLLNVAL bedeutet, dass der Socket-Dateideskriptor nicht geöffnet ist. Es wäre ein Fehler zu close() it.

    
jxh 16.07.2014, 22:23
quelle
8

Es hängt von der genauen Fehlerart ab. Verwenden Sie getsockopt (), um das Problem zu sehen:

%Vor%

Werte: Ссылка

Der einfachste Weg ist anzunehmen, dass der Socket in jedem Fall nicht mehr benutzbar ist und schließe ihn.

    
hasan 16.07.2014 22:17
quelle
2

POLLNVAL bedeutet, dass der Dateideskriptorwert ungültig ist. In der Regel weist dies auf einen Fehler in Ihrem Programm hin. Sie können sich jedoch darauf verlassen, dass poll POLLNVAL zurückgibt, wenn Sie einen Dateideskriptor geschlossen haben und seither keine Datei geöffnet haben, die den Deskriptor möglicherweise wiederverwendet hat.

POLLERR ähnelt Fehlerereignissen von select . Es zeigt an, dass ein Aufruf read oder write eine Fehlerbedingung (z. B. E / A-Fehler) zurückgeben würde. Dies beinhaltet nicht Out-of-Band-Daten, die select über ihre errorfds -Maske, sondern poll -Signale über POLLPRI signalisiert.

POLLHUP bedeutet im Grunde, dass das Ende der Verbindung am Ende der Verbindung beendet ist. POSIX beschreibt es als

  

Das Gerät wurde getrennt. Diese Veranstaltung und POLLOUT schließen sich gegenseitig aus; Ein Stream kann niemals beschreibbar sein, wenn ein Aufhängen aufgetreten ist.

Dies ist für ein Terminal klar genug: das Terminal ist verschwunden (dasselbe Ereignis, das einen SIGHUP erzeugt: die Modem-Sitzung wurde beendet, das Terminal-Emulator-Fenster wurde geschlossen usw.). POLLHUP wird niemals für eine normale Datei gesendet. Für Pipes und Sockets ist vom Betriebssystem abhängig . Linux setzt POLLHUP , wenn das Programm am Schreibende einer Pipe die Pipe schließt und POLLIN|POLLHUP setzt, wenn das andere Ende eines Sockets den Socket schließt, aber POLLIN nur für einen Socket-Shutdown. Recent * BSD set POLLIN|POLLUP , wenn das Schreibende einer Pipe die Pipe schließt und das Verhalten für Sockets variabler ist.

    
Gilles 11.08.2014 18:26
quelle
0

Minimales FIFO-Beispiel

Sobald Sie verstehen, wann diese Bedingungen eintreten, sollte es einfach sein zu wissen, was Sie damit machen sollen.

%Vor%

Kompilieren mit:

%Vor%

Verwendung:

%Vor%

Auf einer anderen Shell:

%Vor%

POLLHUP

Wenn Sie die Quelle nicht ändern: ./poll.out outputs:

%Vor%

Also:

  • POLLIN passiert, wenn die Eingabe verfügbar wird
  • POLLHUP passiert, wenn die Datei von printf geschlossen wird
  • close(pfd.fd); und pfd.fd *= -1; bereinigen die Dinge und wir hören auf, POLLHUP zu erhalten
  • poll bleibt für immer hängen

Dies ist die normale Operation.

Sie könnten jetzt den FIFO neu einstellen, um auf den nächsten open zu warten oder die Schleife zu beenden, wenn Sie fertig sind.

POLLNAL

Wenn Sie pfd.fd *= -1; auskommentieren: ./poll.out druckt:

%Vor%

und wiederholt für immer.

Also:

  • POLLIN und POLLHUP und close passiert wie zuvor
  • Da wir pfd.fd nicht auf eine negative Zahl gesetzt haben, versucht poll weiterhin, die von uns geschlossene fd
  • zu verwenden
  • Dies führt immer zu POLLNVAL forever

Wir sehen also, dass dies nicht passiert sein sollte, und zeigt einen Fehler in Ihrem Code an.

POLLERR

Ich weiß nicht, wie ich POLLERR mit FIFOs erzeugen kann. Lass es mich wissen, wenn es einen Weg gibt. Aber es sollte mit file_operations eines Gerätetreibers möglich sein.

Getestet in Ubuntu 14.04.

    
quelle