Dans une connexion socket non bloquante, select () renvoie toujours 1

J’ai ce segment de code conçu pour se connecter à un serveur via une connexion socket. Toutefois, s’il ne parvient pas à se connecter au serveur dans un certain délai, j’aimerais qu’il cesse d’essayer. J’ai essayé de faire cela avec ce socket non bloquant et la commande select mais select renvoie toujours 1, indiquant que le serveur existe quand rien n’existe à l’adresse que je lui donne. Des idées?

SOCKET tcp_client( char *hname, char *sname ) { fd_set fdset; struct sockaddr_in peer; SOCKET s; FD_ZERO(&fdset); // FD_SET(STDIN, &fdset); FD_SET(s, &fdset); errno=1; struct timeval tv; tv.tv_sec = 15; set_address( hname, sname, &peer, "tcp" ); s = socket( AF_INET, SOCK_STREAM, 0 ); int n = 1; fcntl(s, F_SETFL, O_NONBLOCK); if ( !isvalidsock( s ) ) { printf("Socket Call Failed: %s\n", strerror(errno)); return(0); } int x = 0; int status = connect( s, ( struct sockaddr * )&peer, sizeof( peer ) ); if(status < 0) { printf("Status: %i\n", status); } int retVal = select(s+1, &fdset, NULL, NULL, &tv); printf("retVal: %i\n", retVal); if (retVal == 1) { int so_error; socklen_t slen = sizeof so_error; getsockopt(s, SOL_SOCKET, SO_ERROR, &so_error, &slen); if (so_error == 0) { printf("work\n"); x =1; } else { printf("fail\n"); x = 0; } } else { printf("noSocks\n"); } if (x ==0 ) { printf("Connect Failed: %s\n", strerror(errno)); L("libOnexc: Connect to socket failed"); close(s); return(0); } return s; } 

Un problème que je vois est que vous vous en tenez au fdset avant de créer le socket. Vous devez faire le

 FD_SET(s, &fdset); 

Une fois que vous avez créé le socket, car s n’est qu’un entier et ne sera donc pas la bonne valeur avant l’appel de socket ().

MODIFIER

Comme ça:

 . . . SOCKET s; errno=1; struct timeval tv; tv.tv_sec = 15; set_address( hname, sname, &peer, "tcp" ); s = socket( AF_INET, SOCK_STREAM, 0 ); int n = 1; fcntl(s, F_SETFL, O_NONBLOCK); if ( !isvalidsock( s ) ) { printf("Socket Call Failed: %s\n", strerror(errno)); return(0); } FD_ZERO(&fdset); FD_SET(s, &fdset); // don't put socket in set until it is actually created 

Vous devez vérifier si le socket est prêt pour l’écriture (le deuxième argument fd_set * à sélectionner) et non pour la lecture (le premier).