Connect non bloquant en TCP
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
#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 :)