Utiliser select () pour que les sockets non bloquants se connectent renvoie toujours 1

Cette question est très similaire (ou presque identique) à Dans une connexion socket non bloquante, select () renvoie toujours 1 ; Cependant, je n’arrive pas à trouver où mon code faiblit.

J’utilise des sockets non-bloquants et je veux utiliser select () lors de la connexion d’un client à un serveur pour vérifier le délai / succès. Le problème est que select () renvoie toujours 1 presque immédiatement, même lorsque le serveur n’est pas en cours d’exécution et qu’il n’y a rien à connecter. Merci d’avance pour l’aide, l’extrait de code est comme suit:

//Loop through the addrinfo structs and try to connect to the first one we can for(p = serverinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { //We couldn't create the socket, try again perror("client: socket"); continue; } //Set the socket to non-blocking int flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) { //The error was something other than non-block/in progress, try next addrinfo if(errno != EINPROGRESS) { close(sockfd); perror("client: connect"); continue; } fd_set write_fds; FD_ZERO(&write_fds); //Zero out the file descriptor set FD_SET(sockfd, &write_fds); //Set the current socket file descriptor into the set //We are going to use select to wait for the socket to connect struct timeval tv; //Time value struct declaration tv.tv_sec = 5; //The second portion of the struct tv.tv_usec = 0; //The microsecond portion of the struct //DEBUG: This is ALWAYS 1 int select_ret = select(sockfd + 1, NULL, &write_fds, NULL, &tv); cout << select_ret << endl; //Check return, -1 is error, 0 is timeout if(select_ret == -1 || select_ret == 0) { //We had an error connecting cout << "Error Connecting\n"; close(sockfd); continue; } } //We successfully connected, break out of loop break; } 

Que voulez-vous que select () retourne? Considérez que select () est normalement utilisé pour attendre plusieurs descripteurs de fichier – si vous en connectiez deux , comment savoir lequel a réussi / échoué en se basant uniquement sur la valeur de retour de select? Vous ne voudriez pas, évidemment.

C’est pourquoi select () vous indique simplement quels descripteurs de fichier ont été modifiés, et vous êtes censé déterminer de manière indépendante ce que c’était. Dans le cas de connect (), vous devez appeler getsockopt () pour récupérer le résultat de la tentative de connexion. Voir cette réponse où j’explique comment faire un connect () non bloquant.

Lorsque vous vous connectez en mode non bloquant et que select () indique que la connexion est accessible en écriture, vous devez alors appeler connect () à nouveau. Cela retournera -1 avec errno == ECONNRESET ou quoi que ce soit.