2009-08-25 3 views
8

Si un serveur TCP et un client sont connectés, je voudrais déterminer quand le client n'est plus connecté. J'ai pensé que je peux simplement faire ceci en essayant d'envoyer un message au client et une fois que send() revient avec un -1, je peux alors démonter le socket. Cette implémentation fonctionne sous Windows mais à la minute où j'essaye de le faire sous Linux avec des sockets BSD, l'appel à send() sur l'application côté serveur fait planter mon application serveur si le client n'est plus connecté. Il ne retourne même pas -1 ... juste termine le programme.L'envoi TCP ne renvoie pas cause de plantage processus

Veuillez expliquer pourquoi cela se produit. Merci d'avance!

Répondre

13

Ceci est causé par le signal SIGPIPE. Voir send(2):

La fonction d'envoi() doit échouer si:
[EPIPE] La prise est fermée pour l'écriture ou la prise est en mode de connexion et n'est plus connecté. Dans ce dernier cas, et si le socket est de type SOCK_STREAM ou SOCK_SEQPACKET et que l'indicateur MSG_NOSIGNAL n'est pas défini, le signal SIGPIPE est généré dans le thread appelant.

Vous pouvez éviter cela en utilisant le drapeau MSG_NOSIGNAL sur l'appel send(), ou en ignorant le signal SIGPIPE avec signal(SIGPIPE, SIG_IGN) au début de votre programme. Ensuite, la fonction send() renverra -1 et définira errno à EPIPE dans cette situation.

2

Vous devez ignorer le signal SIGPIPE. Si une erreur d'écriture se produit sur un socket, votre processus avec get SIGPIPE, et le comportement par défaut de ce signal est de tuer votre processus. Ecrit le code réseau sur * nix que vous voulez habituellement:

signal(SIGPIPE,SIG_IGN); 
Questions connexes