Wenn ein TCP-Server und ein Client verbunden sind, möchte ich feststellen, wann der Client nicht mehr verbunden ist. Ich dachte, ich kann das einfach tun, indem ich versuche, eine Nachricht an den Client zu senden, und sobald send () mit einer -1 zurückkehrt, kann ich den Socket abreißen. Diese Implementierung funktioniert unter Windows, aber sobald ich dies unter Linux mit BSD-Sockets versuche, verursacht der Aufruf von send () auf der serverseitigen App, dass meine Server-App abstürzt, wenn der Client nicht mehr verbunden ist. Es gibt nicht einmal eine -1 zurück ... beendet nur das Programm.
Bitte erläutern Sie, warum dies geschieht. Vielen Dank im Voraus!
Dies wird durch das Signal SIGPIPE verursacht. Siehe send(2)
:
Die Funktion send () soll fehlschlagen, wenn:
[EPIPE] Der Socket wird zum Schreiben heruntergefahren, oder der Socket ist Verbindungsmodus und ist nicht mehr verbunden. Im letzteren Fall und wenn der Socket vom Typ SOCK_STREAM oder SOCK_SEQPACKET ist und das Flag MSG_NOSIGNAL nicht gesetzt ist, wird das SIGPIPE-Signal für den aufrufenden Thread erzeugt.
Sie können dies vermeiden, indem Sie das Flag MSG_NOSIGNAL
für den Aufruf send()
verwenden oder indem Sie das Signal SIGPIPE
mit signal(SIGPIPE, SIG_IGN)
zu Beginn Ihres Programms ignorieren. Dann wird die Funktion send()
-1 zurückgeben und in dieser Situation errno
auf EPIPE
setzen.
Sie müssen das Signal SIGPIPE ignorieren. Wenn ein Schreibfehler an einem Socket auftritt, wird Ihr Prozess mit SIGPIPE abgefangen, und das Standardverhalten dieses Signals besteht darin, Ihren Prozess zu beenden. Schreiben Sie den Netzwerkcode auf * nix, den Sie normalerweise wollen:
%Vor%