xilebo noone | Bonjour ,
Je tente de rendre un connect non bloquant, le but étant de ne pas bloquer 30 sec lorsqu'on tente de se connecter sur une machine qui n'existe pas.
J'ai donc utilisé du code trouvé sur internet, qui fonctionne sous windows, mais pas sous linux.
Voici le code linux :
Code :
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- int main()
- {
- int mysocket;
- mysocket = socket( AF_INET , SOCK_STREAM , IPPROTO_TCP );
- if ( mysocket >= 0)
- {
- unsigned long hote_l;
- hote_l = inet_addr( "172.17.0.140" );
- struct sockaddr_in adresse;
- memset ( &adresse , 0 , sizeof( adresse ) );
- adresse.sin_family = AF_INET;
- adresse.sin_addr.s_addr = hote_l;
- adresse.sin_port = htons( 40001 );
- // rendre l'appel connect non bloquant pour changer le temps d'attente de la connexion
- int flags;
- int r;
- flags = fcntl (mysocket, F_GETFL);
- r = fcntl (mysocket, F_SETFL, flags | O_NONBLOCK);
- int ret_connect = connect( mysocket , (struct sockaddr *) &adresse , sizeof (adresse ) );
- if ( ret_connect != 0) // echec , attendre que ca se soit bien connecté
- {
- if ( errno == EINPROGRESS )
- {
- struct timeval timeout_connect;
- timeout_connect.tv_sec = 2;
- timeout_connect.tv_usec = 0;
- fd_set fd_connect_read;
- fd_set fd_connect_write;
- fd_set fd_connect_err;
- FD_ZERO(&fd_connect_read);
- FD_SET(mysocket, &fd_connect_read);
- FD_ZERO(&fd_connect_write);
- FD_SET(mysocket, &fd_connect_write);
- FD_ZERO(&fd_connect_err);
- FD_SET(mysocket, &fd_connect_err );
- int rcode = select((int) mysocket+1, /*&fd_connect_read*/ NULL, &fd_connect_write, /*&fd_connect_err*/ NULL , &timeout_connect);
- if ( rcode > 0 )
- {
- if ( FD_ISSET( mysocket , &fd_connect_write ))
- {
- // ok
- printf(" ne devrait pas être là\n" );
- }
- }
- else if ( rcode == 0 ) // timeout , pas de connexion
- {
- printf("le serveur n'est pas là\n" );
- }
- else
- {
- printf("select a échoué\n" );
- }
- }
- else
- {
- printf("connect a échoué\n" );
- }
- }
- r = fcntl (mysocket, F_SETFL, flags & ~O_NONBLOCK);
- close( mysocket);
- }
- return 0;
- }
|
normalement, le select ne devrait pas renvoyer 1 mais 0.
Le comportement sous windows est différent : on n'utilise pas fcntl mais ioctl pour rendre non bloquant, et le select renvoie bien 1 mais il faut tester fd_connect_err qui signifie qu'il y a bien une erreur s'il est positionné.
Où ai-je pu faire une erreur ?
Merci |