Dans la programmation de socket dans Linux, je dois écrire des données dans la prise, mais je ne sais pas que la prise est ouverte ou proche. Comment savoir que je sais que cette prise est ouverte et ferme sans lire? J'ai lu depuis SOCKFD et je suis sûr que cette connexion est ouverte. Quand écrire un tampon dans Newsockfd, je ne sais pas Newockfd est ouvert ou fermer comment vérifier Newockfd est fermé? P> Je connais le problème. au milieu de la connexion d'écriture fermée. Par exemple, écrire 1024 données en 500 Connexion fermée et programmée fermée. Comment éviter cela? p> p>
3 Réponses :
Le moyen de vérifier si vous pouvez écrire sur une prise, c'est étonnamment, d'essayer de vous écrire: -)
Si la prise a été fermée, vous obtiendrez un Si la prise est toujours valide mais que vous ne pouvez pas écrire Toute données pour le moment, Fondamentalement, pour Mise à jour: EM> Comme la CAF a souligné dans les commentaires, j'ai oublié de prendre en compte la manipulation du signal. Vous devez ignorer le signal de tuyau cassé ou Vous pouvez le faire en insertant: p> -1 code> code de retour de
écrire code> et vous pouvez examiner
errno code> pour voir quel était le problème. p>
écriture code> retournera 0. L'appel code> Lecture code> se comporte également de la même manière, renvoyant
-1 code> s'il y a un problème. p>
écrire code>: p>
-1 code>, il y a eu un problème et vous devriez vérifier
errno code> pour voir si elle est recouvrable ou fatale. Li>
0 code>, vous ne pouvez rien écrire pour le moment (peut être un arriéré réseau ou un autre problème, mais certainement, pas (encore) fatal). LI>
écrire code> échouera en interne en augmentant ce signal. P>
sigaction (SIGPIPE, &old_actn, NULL);
Dans la ligne suivante, voir si (n <= 0) mais en fonction de la fonction d'écriture, une erreur s'est produite et fermée
@Sjb, do pas i> suppose des problèmes si écrire code> retourne 0. Cela peut se produire s'il y a un arriéré de réseau temporaire. Si l'arriéré tourne dans un vrai problème, la session sera arrêtée et vous finirez par obtenir -1. Jusque-là, continuez à essayer.
Je connais le problème. au milieu de la connexion d'écriture fermée. Par exemple, écrire 1024 données en 500 Connexion fermée et programmée fermée
PAX, vous oubliez que, par défaut, essayez de code> écrire code> sur la prise fermé par l'autre extrémité entraînera la rétention de votre processus de rétention d'un signal Sigpipe code>, dont l'action par défaut de laquelle est de mettre fin au processus.
Mon erreur. Corrigé maintenant (espérons-le).
La programmation de la prise peut être plutôt délicate, car vous ne savez souvent pas qu'une erreur s'est produite tant que plus tard. P>
Par exemple, si la machine que vous écrivez pour s'éteindre anormalement, l'appel d'écriture peut réussir (car vous avez pu écrire sur vos tampons d'exploitation internes), seulement pour échouer pendant l'appel proche. P>
Sauf si vous avez une méthode de vérification de la couche d'application de vérification du socket (c'est-à-dire envoyer un message et nécessitant une réponse dans une période de temps), vous n'avez aucun moyen de savoir. Si vous utilisez un protocole standard, quelque chose peut déjà exister pour gérer les erreurs. P>
La réponse courte est donc que vous devez vérifier les retours d'erreur de chaque appel qui touche la prise (lecture, écriture, fermeture, etc.). p>
Malheureusement, c'est la bonne réponse. J'ai essayé quelques façons de savoir si les connexions HTTP conservées sont toujours valables, mais ce n'est pas fiable et sans conditions de course.
J'utilise Envoyer () Écrivez () qui ne traite aucun signal:
Cela fonctionnera et l'autre alternative est d'utiliser sigaction code> pour ignorer
sigpipe code> (définir son gestionnaire sur
sig_ign code>).