GNU/Linux >> Tutoriels Linux >  >> Linux

Linux, sockets, connexion non bloquante

Vous devez suivre les étapes suivantes pour une connexion asynchrone :

  • créer un socket avec socket(..., SOCK_NONBLOCK, ...)
  • démarrer la connexion avec connect(fd, ...)
  • si la valeur de retour n'est ni 0 ni EINPROGRESS , puis abandon avec erreur
  • attendre fd est signalé comme prêt pour la sortie
  • vérifier l'état du socket avec getsockopt(fd, SOL_SOCKET, SO_ERROR, ...)
  • fait

Pas de boucles - sauf si vous voulez gérer EINTR .

Si le client est démarré en premier, vous devriez voir l'erreur ECONNREFUSED dans la dernière étape. Si cela se produit, fermez le socket et recommencez depuis le début.

Il est difficile de dire ce qui ne va pas avec votre code, sans voir plus de détails. Je suppose que vous n'abandonnez pas sur des erreurs dans votre check_socket opération.


Il existe plusieurs façons de tester si une connexion non bloquante réussit.

  1. appelez d'abord getpeername(), s'il a échoué avec l'erreur ENOTCONN, la connexion a échoué. puis appelez getsockopt avec SO_ERROR pour obtenir l'erreur en attente sur le socket
  2. appelez read avec une longueur de 0. si la lecture a échoué, la connexion a échoué, et l'errno for read indique pourquoi la connexion a échoué ; read renvoie 0 si la connexion réussit
  3. appeler à nouveau la connexion ; si l'errno est EISCONN, la connexion est déjà établie et la première connexion a réussi.

Réf :Programmation réseau UNIX V1


D. J. Bernstein a rassemblé diverses méthodes pour vérifier si un connect() asynchrone appel réussi ou non. Beaucoup de ces méthodes présentent des inconvénients sur certains systèmes, il est donc difficile d'écrire du code portable pour cela. Si quelqu'un veut lire toutes les méthodes possibles et leurs inconvénients, consultez ce document.

Pour ceux qui veulent juste la version tl;dr, le moyen le plus portable est le suivant :

Une fois que le système signale le socket comme accessible en écriture, appelez d'abord getpeername() pour voir s'il est connecté ou non. Si cet appel a réussi, le socket est connecté et vous pouvez commencer à l'utiliser. Si cet appel échoue avec ENOTCONN , la connexion a échoué. Pour savoir pourquoi il a échoué, essayez de lire un octet du socket read(fd, &ch, 1) , qui échouera également mais l'erreur que vous obtenez est l'erreur que vous auriez obtenue de connect() s'il n'était pas non bloquant.


Linux
  1. Communication inter-processus sous Linux :Sockets et signaux

  2. Connectez-vous à un serveur en utilisant SSH sous Linux ou Mac OS X

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

  4. API Linux pour déterminer les sockets appartenant à un processus

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

Comment se connecter à un poste de travail distant à partir de Linux

Comment se connecter via Bluetooth dans GNOME sous Linux

Comment connecter l'iPhone à Arch Linux

Comment se connecter à SQL Server à partir de Linux

Comment se connecter avec Samba à Linux Active Directory

Gestionnaire de connexion CLI Linux ?