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
niEINPROGRESS
, 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.
- 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
- 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
- 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.