J’ai un socket bloquant (du moins il apparaît dans le code suivant):
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock < 0) { ERROR("%s: error opening socket", __func__); return (RESP_ERROR); } t.tv_sec = timeout; t.tv_usec = 0; int rf = fcntl(sock, F_GETFD); ERROR("fcntl ret=%d, ret & O_NONBLOCK = %d", rf, rf & O_NONBLOCK); if ((setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&t, sizeof (t)) %s", __func__, err); close(sock); return (RESP_ERROR); } rf = fcntl(sock, F_GETFD); ERROR("after select fcntl ret=%d, ret & O_NONBLOCK = %d", rf, rf & O_NONBLOCK); if (connect(sock, (struct sockaddr *)&dst, sizeof (dst)) != 0) { strerror_r(errno, err, 254); ERROR("%s: error on connect -> %s", __func__, err); close(sock); return (RESP_ERROR); }
Et c’est à partir du journal:
6 mars 10:42:04 tcpclient: fcntl ret = 0, ret & O_NONBLOCK = 0
6 mars 10:42:04 tcpclient: après select fcntl ret = 0, ret & O_NONBLOCK = 0
- Comment savoir quel port série utiliser sous Linux?
- Le programme c ++ se bloque lorsqu’il est lié à deux bibliothèques partagées tierces
- Gestion correcte des erreurs pour fclose impossible (selon la page de manuel)?
- Double socket vs modèle de mémoire à socket unique?
- Exemple de dessin de pixels OpenGL / PBO nécessaire
6 mars 10:42:14 tcpclient: authentifier: erreur lors de la connexion -> Opération en cours
Il semble que ce soit une prise bloquante mais renvoie une erreur typique pour non-blocage? Linux est 2.6.18-308.el5. Des idées?
Si timeout
n’est pas 0
l’appel à la connect()
expire et revient. Cela se produit indépendamment du fait qu’une connexion ait été établie ou non.
À partir du moment où le délai d’expiration a expiré, connect()
se comporte comme s’il était appelé sur un socket non bloquant.
En référant ce cas (verbatim de man connect
et ignore ” immédiatement ” ci-dessous):
EINPROGRESS
Le socket n’est pas bloquant et la connexion ne peut pas être terminée immédiatement. Il est possible de sélectionner (2) ou d’interroger (2) pour terminer en sélectionnant le socket pour l’écriture. Une fois que select (2) indique la possibilité d’écriture, utilisez getsockopt (2) pour lire l’option SO_ERROR au niveau SOL_SOCKET afin de déterminer si connect () a abouti (SO_ERROR est à zéro) ou sans succès (SO_ERROR la raison de l’échec).
Btw: Quelqu’un pourrait-il confirmer qu’il s’agit d’un comportement standard, et pour cela explicitement mentionné quelque part?
man 7 socket
états des man 7 socket
(italiques par moi):
SO_RCVTIMEO et SO_SNDTIMEO
Spécifiez le délai de réception ou d’envoi jusqu’à la notification d’une erreur. […] si aucune donnée n’a été transférée et que la temporisation a été atteinte, -1 est renvoyé avec errno avec EAGAIN ou EWOULDBLOCK, comme si la socket avait été spécifiée comme non bloquante . […] Les délais d’attente n’ont d’effet que pour les appels système qui effectuent des E / S de socket (par exemple, read (2), recvmsg (2), send (2), sendmsg (2)); les timeouts n’ont aucun effet pour select (2), poll (2), epoll_wait (2), etc.
Aucun mot concernant connect()
alors je ne suis pas sûr que ma réponse soit valide.
Essayez-le avec ‘if ((connect (…)) <0)'. Vous ne recevez peut-être pas d'erreur du tout.