Was verursacht den Rohrbruchfehler?

Lesezeit: 3 Minuten

Benutzeravatar von Jay
Jay

Ich weiß, dass ein Pipe-Fehler ausgelöst wird, wenn der Socket auf der Peer-Seite geschlossen wird.

Aber in meinem Test habe ich festgestellt, dass ein sofortiger ‘Send’-Aufruf auf dieser Seite, wenn die Peer-Seite geschlossen ist, nicht immer zu einem Rohrbruchfehler führt.

Z.B:

Nach dem Schließen des Sockets auf der Peer-Seite (ich habe ein sauberes Schließen durch Aufrufen von close und auch ein abnormales Schließen durch Beenden des Peers versucht), wenn ich versuche, 40 Bytes zu senden, bekomme ich keine kaputte Pipe, aber wenn ich es versuche Senden Sie 40000 Bytes, dann gibt es sofort einen Rohrbruchfehler.

Was genau verursacht einen Rohrbruch und kann sein Verhalten vorhergesagt werden?

Es kann einige Zeit dauern, bis das Schließen des Netzwerks beobachtet wird – die Gesamtzeit beträgt nominell etwa 2 Minuten (ja, Minuten!) nach einem Schließen, bevor angenommen wird, dass alle für den Port bestimmten Pakete tot sind. Der Fehlerzustand wird irgendwann erkannt. Mit einem kleinen Schreibvorgang befinden Sie sich innerhalb der MTU des Systems, sodass die Nachricht zum Senden in die Warteschlange gestellt wird. Bei einem großen Schreibvorgang sind Sie größer als die MTU und das System erkennt das Problem schneller. Wenn Sie das SIGPIPE-Signal ignorieren, geben die Funktionen einen EPIPE-Fehler bei einer unterbrochenen Leitung zurück – an einem Punkt, an dem die Unterbrechung der Verbindung erkannt wird.

  • @varevarao: Ich denke nicht, dass das Einreihen von Übertragungen und das Senden in bestimmten Intervallen eine Problemumgehung ist. Übertragungen in die Warteschlange zu stellen, bis mehr als die MTU zu senden ist, könnte eine Problemumgehung sein, wenn Ihre Anwendung mit den Verzögerungen leben kann.

    – Jonathan Leffler

    13. Dezember 2012 um 16:10 Uhr

  • Ich denke, dass es sehr damit zusammenhängt en.wikipedia.org/wiki/Nagle%27s_algorithm

    – Sekt

    1. Februar 2021 um 9:48 Uhr

  • MTU: en.wikipedia.org/wiki/Maximum_transmission_unit

    – TheRealFakeNews

    9. November 2021 um 19:34 Uhr

Benutzeravatar von Vikram.exe
Vikram.exe

Der aktuelle Zustand eines Sockets wird durch “Keep-Alive”-Aktivität bestimmt. In Ihrem Fall ist dies möglich, wenn Sie die send Ruf den keep-alive Aktivität sagt, dass der Socket aktiv ist und so die send call schreibt die erforderlichen Daten (40 Byte) in den Puffer und kehrt ohne Fehler zurück.

Wenn Sie einen größeren Chunk senden, wechselt der Send-Aufruf in den Sperrzustand.

Die Send-Manpage bestätigt dies auch:

Wenn die Nachricht nicht in den Sendepuffer des Sockets passt, blockiert send() normalerweise, es sei denn, der Socket wurde in den nicht blockierenden E/A-Modus versetzt. Im nicht blockierenden Modus würde es in diesem Fall EAGAIN zurückgeben

Wenn also beim Blockieren für den frei verfügbaren Puffer der Anrufer benachrichtigt wird (durch den Keep-Alive-Mechanismus), dass das andere Ende nicht mehr vorhanden ist, schlägt der Sendeaufruf fehl.

Das genaue Szenario vorherzusagen ist mit den genannten Informationen schwierig, aber ich glaube, dies sollte der Grund für Ihr Problem sein.

  • Der aktuelle Zustand des Sockets wird durch ACK-Aktivität überwacht. Keepalive ist nur eine geringfügige Quell-ACK-Aktivität und standardmäßig deaktiviert.

    – Benutzer207421

    12. Januar 2016 um 19:01 Uhr

Benutzeravatar von Joel
Joel

Vielleicht passen die 40 Bytes in den Pipe-Puffer und die 40000 Bytes nicht?

Bearbeiten:

Der sendende Prozess erhält ein SIGPIPE-Signal, wenn Sie versuchen, in eine geschlossene Pipe zu schreiben. Ich weiß nicht genau, wann das Signal gesendet wird oder welche Auswirkung der Pipe-Puffer darauf hat. Sie können sich möglicherweise erholen, indem Sie das Signal mit dem Sigaction-Anruf abfangen.

Wenn der Peer geschlossen wird, wissen Sie einfach nicht, ob er nur aufhört zu senden oder sowohl sendet als auch empfängt. Da TCP dies zulässt, sollten Sie übrigens den Unterschied zwischen Schließen und Herunterfahren kennen. Wenn der Peer sowohl das Senden als auch das Empfangen beendet, senden Sie zuerst einige Bytes, es wird erfolgreich sein. Aber der Peer-Kernel sendet Ihnen RST. Wenn Sie also anschließend einige Bytes senden, sendet Ihr Kernel Ihnen ein SIGPIPE-Signal, wenn Sie dieses Signal abfangen oder ignorieren, wenn Ihr Senden zurückkehrt, erhalten Sie einfach einen Broken-Pipe-Fehler, oder wenn Sie dies nicht tun, stürzt das Standardverhalten Ihres Programms ab .

1420790cookie-checkWas verursacht den Rohrbruchfehler?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy