GNU/Linux >> Tutoriels Linux >  >> Linux

Vérifier la connexion ouverte ou fermée ? (en C sous Linux)

J'utilise send() à la place write() qui ne gère aucun signal :

bzero(buffer, MAX_SIZE_BUFFER);
n = read(sockfd, buffer, MAX_SIZE_BUFFER - 1);
printf("after read%d\n", n);
if (n <= 0)
{
    break;
}
n2 = send(newsockfd, buffer, n, MSG_NOSIGNAL);
if (n2 == -1)
{
    close(sockfd);
    close(newsockfd);
    return;
}
if (n2 != n)
{
    break;
}

La programmation de socket peut être assez délicate, car vous ne savez souvent qu'une erreur s'est produite que bien plus tard.

Par exemple, si la machine sur laquelle vous écrivez s'arrête anormalement, l'appel d'écriture peut réussir (car vous avez pu écrire dans les tampons internes de votre système d'exploitation), mais échouer lors de l'appel de fermeture.

À moins que vous ne disposiez d'un moyen de couche application pour vérifier que le socket est actif (c'est-à-dire envoyer un message et exiger une réponse dans un certain délai), vous n'avez aucun moyen de le savoir. Si vous utilisez un protocole standard, quelque chose existe peut-être déjà pour gérer les erreurs.

Donc, la réponse courte est que vous devez vérifier les retours d'erreur de presque tous les appels qui touchent le socket ( lecture, écriture, fermeture, etc... ).


La façon de vérifier si vous pouvez écrire sur un socket est, étonnamment, d'essayer d'y écrire :-)

Si le socket a été fermé, vous obtiendrez un -1 code de retour de write et vous pouvez examiner errno pour voir quel était le problème.

Si le socket est toujours valide mais que vous ne pouvez pas écrire de données pour le moment, write renverra 0. Le read call se comporte également de la même manière, renvoyant -1 en cas de problème.

En gros, pour write :

  • si vous récupérez un -1 , il y a eu un problème et vous devriez vérifier errno pour voir s'il est récupérable ou fatal.
  • Si vous récupérez un 0 , alors vous ne pouvez rien écrire pour le moment (peut-être un backlog réseau ou un autre problème mais certainement pas (encore) fatal).
  • Si vous obtenez une valeur inférieure à ce que vous vouliez, alors certains des données ont été envoyées. Ajustez vos pointeurs pour pouvoir essayer d'envoyer le reste au cycle suivant. Ne pas supposons qu'une valeur de retour positive signifie que le bloc entier a été envoyé.
  • Si vous récupérez le même nombre que le nombre d'octets que vous avez essayé d'envoyer, le tampon entier a été accepté pour livraison.
  • Si vous recevez plus que ce que vous avez demandé, envoyez un e-mail aux développeurs du noyau avec un commentaire acerbe. Linus et al vont adorer ça :-)

Mettre à jour : Comme caf l'a souligné dans les commentaires, j'ai oublié de prendre en compte la gestion du signal. Vous devez ignorer le signal de tuyau cassé ou write échouera en interne en élevant ce signal.

Vous pouvez le faire en insérant :

struct sigaction new_actn, old_actn;
new_actn.sa_handler = SIG_IGN;
sigemptyset (&new_actn.sa_mask);
new_actn.sa_flags = 0;
sigaction (SIGPIPE, &new_actn, &old_actn);

avant de commencer à utiliser les fonctions de socket. Vous pouvez ensuite utiliser :

sigaction (SIGPIPE, &old_actn, NULL);

pour restaurer le traitement du signal précédent.


Linux
  1. Comment vérifier l'écoute / les ports ouverts avec Netstat sous Linux

  2. Vérifier la limite FD ouverte pour un processus donné sous Linux

  3. presse-papiers linux lire/écrire en C

  4. Comment écrire un pilote de périphérique de bloc linux en espace utilisateur?

  5. vérifier tous les sockets ouverts dans le système d'exploitation Linux

Que sont les ports ? Comment vérifier les ports ouverts Linux ?

Comment vérifier les ports ouverts sous Linux

Comment vérifier qu'un port est ouvert sur un système Linux distant

Comment vérifier tous les ports ouverts de votre système Linux

Comment vérifier les ports ouverts sous Linux ?

Toutes les façons de vérifier si un port est ouvert sous Linux