Der TCP -SENT kehrt keinen Ursache zum Absturzprozess zurück
Frage
Wenn ein TCP -Server und ein Client verbunden sind, möchte ich feststellen, wann der Client nicht mehr verbunden ist. Ich dachte, ich kann dies einfach tun, indem ich versuche, eine Nachricht an den Kunden zu senden, und sobald Send () mit einem -1 zurückkehrt, kann ich den Sockel abreißen. Diese Implementierung funktioniert unter Windows, aber in dem Minute, in dem ich dies unter Linux mit BSD -Sockets mache, wird der Anruf an sendet () auf der Server -Seite -App zum Absturz, wenn der Client nicht mehr verbunden ist. Es gibt nicht einmal eine -1 zurück ... nur das Programm.
Bitte erklären Sie, warum dies geschieht. Danke im Voraus!
Lösung
Dies wird durch das Sigpipe -Signal verursacht. Sehen send(2)
:
Die Funktion send () muss fehlschlagen, wenn:
Epipe] Der Sockel wird zum Schreiben heruntergefahren, oder der Sockel ist Verbindungsmodus und ist nicht mehr angeschlossen. Im letzteren Fall und wenn der Socket vom Typ sock_stream oder sock_seqpacket ist und das MSG_NOSIGNAL -Flag nicht eingestellt ist, wird das Sigpipe -Signal für den aufrufenden Thread generiert.
Sie können dies vermeiden, indem Sie die verwenden MSG_NOSIGNAL
Flagge auf der send()
anrufen oder durch ignorieren SIGPIPE
signalisieren mit signal(SIGPIPE, SIG_IGN)
Zu Beginn Ihres Programms. Dann ist die send()
Die Funktion gibt -1 zurück und setzt errno
zu EPIPE
in dieser Situation.
Andere Tipps
Sie müssen das Sigpipe -Signal ignorieren. Wenn ein Schreibfehler in einem Socket auftritt, Ihr Prozess mit GET Sigpipe und das Standardverhalten dieses Signals besteht darin, Ihren Prozess abzutöten. Schreiben von Networking -Code auf *Nix, das Sie normalerweise möchten:
signal(SIGPIPE,SIG_IGN);