TCP Envoyer ne retourne pas la cause processus s'écraser
Question
Si un serveur tcp et le client est connecté, je voudrais déterminer le moment où le client est plus connecté. Je pensais que je peux simplement faire en essayant d'envoyer un message au client et une fois send () retourne avec -1, je peux alors déchirer la prise. Cette mise en œuvre fonctionne sur Windows, mais trouvent la minute où j'essayer de faire cela sur Linux avec les sockets BSD, l'appel à envoyer () sur l'application côté serveur provoque mon application serveur pour se bloquer si le client n'est plus connecté. Il ne revient même pas -1 ... juste met fin au programme.
S'il vous plaît expliquer pourquoi cela se produit. Merci d'avance!
La solution
Ceci est causé par le signal SIGPIPE. Voir send(2)
:
La fonction send () doit échouer si:
[EPIPE] La douille est fermée pour l'écriture ou la douille est en mode connexion et ne sera plus connecté. Dans ce dernier cas, et si la prise est du type SOCK_STREAM ou SOCK_SEQPACKET et le drapeau MSG_NOSIGNAL est pas défini, le signal SIGPIPE est généré pour le thread appelant.
Vous pouvez éviter cela en utilisant le drapeau MSG_NOSIGNAL
sur l'appel send()
ou en ignorant le signal de SIGPIPE
avec signal(SIGPIPE, SIG_IGN)
au début de votre programme. Ensuite, la fonction sera send()
retournera -1 et errno
à EPIPE
dans cette situation.
Autres conseils
Vous devez ignorer le signal SIGPIPE. Si une erreur d'écriture se produit sur une socket, votre processus avec get SIGPIPE et le comportement par défaut de ce signal est de tuer votre processus. Code réseau écrit sur * nix vous voulez habituellement:
signal(SIGPIPE,SIG_IGN);