2010-05-20 7 views
5

Mon application linux effectue un syscall de connexion TCP non bloquante, puis utilise epoll_wait pour détecter la fin de la prise de contact à trois voies. Parfois, epoll_wait renvoie à la fois POLLOUT & POLLERR événements définis pour le même descripteur de socket. Je voudrais comprendre ce qui se passe au niveau TCP.tcp non bloquant se connecter avec epoll

Je ne suis pas capable de le reproduire à la demande. Ma conjecture est qu'entre deux appels à epoll_wait dans ma boucle d'événement nous avons eu une séquence SYN + ACK/ACK/FIN mais encore je ne suis pas capable de le reproduire.

Répondre

4

Il est probable que cela se produise si la connexion a échoué - par exemple avec « Délai de connexion dépassé » (pour les sockets faire un sans blocage, POLLOUT se fige lorsque l'opération de connexion est terminée pour les résultats positifs et les échecs).

Lorsque POLLOUT devient la socket, utilisez getsockopt(sock, SOL_SOCKET, SO_ERROR, ...) pour vérifier si la connexion a réussi ou non (l'option prise est SO_ERROR 0 dans ce cas, et indique par ailleurs la raison pour laquelle la connexion a échoué).

2

Voici quelques bonnes informations sur non-blocking tcp connect().

Lorsqu'une erreur de socket est détectée (connexion fermée/refusée/temporisée), epoll renvoie les événements d'intérêt enregistrés POLLIN/POLLOUT avec POLLERR. Donc, epoll_wait() retournera POLLOUT | POLLERR si vous avez enregistré POLLOUT, ou POLLIN | POLLOUT | POLLERR si POLLIN | POLLOUT a été enregistré.

Tout simplement parce que epoll renvoie POLLIN ne signifie pas qu'il y aura des données à lire, car recv() peut simplement retourner l'erreur de l'appel connect() non bloquant. Je pense qu'epoll retourne tous les événements enregistrés avec POLLERR pour s'assurer que le programme appelle send()/recv()/etc .. et obtient l'erreur de socket. Certains programmes ne vérifient jamais POLLERR/POLLHUP et ne détectent que les erreurs de socket lors de l'appel send()/recv() suivant.