connect () renvoie “Opération en cours” sur le socket bloquant?

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

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.