[C] Un timeOut sur Socket en détails [Linux]

Signaler
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008
-
Messages postés
14
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
16 juin 2009
-
Salut a tous.

Bon j'ai pas mal cherché sur le site, et appart des débuts de réponses, je n'ai rien trouvé qui m'ai aidé à résoudre ce problème de TimeOut sur un connect() ou un Read().

Moi pour le read(), j'ai créé une boucle while pour essayer de faire une gestion du timeout, mais bon, c'est pas terrible.

Bref, malgret tout mes essaies ( y en pour quelques nuits tout de même ) j'arrive pas à trouver la manière de faire un timeout digne de ce nom.

Ma question : Aurriez vous des exemples de code qui gére un timeout avec des explications si possible ?

Je vous remercie par avance pour le temps que vous m'accorder

ZedMaTriX

21 réponses

Messages postés
56
Date d'inscription
dimanche 13 novembre 2005
Statut
Membre
Dernière intervention
11 juillet 2006

regarde si select pour t aider il permet de faire des lecture non bloquante
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008

Ok, ca c'est la réponse que l'on voie partout, mais sinon, tu n'as pas un exemple, pour m'aider ???

Parcque on voie partout select, select, select, mais ca m'aide pas !

Merci beaucoup

ZedMaTriX
Messages postés
56
Date d'inscription
dimanche 13 novembre 2005
Statut
Membre
Dernière intervention
11 juillet 2006

dsl je ne les jamais utiliser mais je connais son fonctionnement

si non la deuxieme solution ce son les termcaps avec le mode canonique ... mais tres casse tete a utilise
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008

Ok, merci c'est pas grave. Sur un autre forum on m'as donné ce lien qui est ma fois super interessant !

http://man.developpez.com/man2/select.2.php

ZedMaTriX
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008

La je lutte un peu ...

Pourriez vous m'aider ?

Voila mon code :

    /* Passe la socket en mode non bloquant */
    fcntl(fdSock, F_SETFL, O_NONBLOCK);
           
    // Connexion du socket au serveur
    connect (fdSock,(struct sockaddr *)&maPrise,sizeof(maPrise));
   
    FD_ZERO(&fSTO);
    FD_SET(fdSock, &fSTO);
   
    ret = select(1, &fSTO, NULL, NULL, &tempLimit);
   
   
    if ( ret == -1 )
    {
           
        perror ("Echec à la connexion : ");
           
        // Ferme la socket
        close(fdSock);
           
        // Quitte
        return 1;
       
    } else if ( ret == 0 )
    {
       
        printf(" Connecté ");
           
    }




J'ai donc déclaré et remplis la struct timeval en donnant 5 pour les secondes.
J'ai aussi fais le fd_set fSTO;

Please, aider moi !

ZedMaTriX
Messages postés
694
Date d'inscription
lundi 5 décembre 2005
Statut
Membre
Dernière intervention
8 janvier 2014
13
Salut,

Une première solution semble être expliquée ici
Cependant, il semble qu'il y ait des soucis avec linux... (man 7 socket)
* SO_RCVTIMEO et SO_SNDTIMEO :
Indiquent le délai maximal d'émission ou de réception avant de renvoyer une erreur.
Sous Linux ces valeurs sont fixées dans les protocoles et ne peuvent être ni lues
ni modifiées. Leurs fonctionnalités peuvent être émulées à  l'aide de alarm (2)

ou setitimer(2).<dt>
Tu peux émuler un timeout avec alarm(). C'est un peu barbare, mais cela fonctionnera si connect() est bloquant en mode interruptible. Ce que je n'ai pas vérifié.

Exemple :

//Tu mets en place un gestionnaire de signal pour capter SIGALRM :
MyAlarm (int sig) { return ; /* Juste pour provoquer la
sortie du mode bloquant */ }




// Tu laisses la socket en mode bloquant

MyConnect () {

            alarm(3) ;
/* délai d’attente de 3 secondes */

            ret = connect(…) ;

            if ( ret != 0 ) {

            switch
(errno) {

case EINTR : /* timeout réalisé
*/



}

}

}
Messages postés
56
Date d'inscription
dimanche 13 novembre 2005
Statut
Membre
Dernière intervention
11 juillet 2006

je crois que tu te trompe un de mes binome a utiliser la fonction select sur l un de nos projet et nous arrivions bien a regle le time et pourtant nous etions sur netbsd ... donc je pense que c'est tout a fait possible aussi sur linux
Messages postés
694
Date d'inscription
lundi 5 décembre 2005
Statut
Membre
Dernière intervention
8 janvier 2014
13
Possible. Je n'ai pas vérifié, juste lu. Si tu peux lui poster la solution de ton binôme, cela pourrait peut être l'aider.
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008

Ouais, s'il te plait ben 92600, ca m'interesserai !

ZedMaTriX
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008

Aider moi s'il vous plait

ZedMaTriX
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008

Je Up

ZedMaTriX
Messages postés
14
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
16 juin 2009

Bonjour,

Bon enfait que veux-tu faire exatement ?

JV
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008

Ben j'ai deux threads par exemple qui se connecte à deux ips différentes.
Toutes les deux ont un service FTP activé.

Mais parfois, une adresse ne répond pas.

Du coups, j'ai un thread qui va s'executer rapidement car l'adresse contacté est bonne, mais le deuxième lui, n'arrive pas à se connecter.

Donc ce que je veux, c'est faire un timeout sur le connect(), de manière que le programme ne reste pas une éternité bloqué.

Apparement select() est tout indiqué pour ca.

Merci de prendre du temps pour moi !

ZedMaTriX
Messages postés
14
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
16 juin 2009

Déjà je te conseille ne pas utiliser de threads car les threads utilsent les mêmes ressource et donc le même connect.
C'est ce qu'on nous conseil à l'école.
Je vais voir ce que je peux faire pour trouver une solution a ton probléme.

JV
Messages postés
14
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
16 juin 2009

Enfait ce que tu veux c'est que ton client puisse ce connnecter à deux server c'est ça ?

JV
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008

Merci caesarvanou pour le temps que tu me consacre ! C'est vraiment sympas !

Ben 2, 3, 4 ... ca dépend du besoin.

ZedMaTriX
Messages postés
14
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
16 juin 2009

Encore une question :
Quand tu dis "Mais parfois, une adresse ne répond pas."
C'est que tu ne peux pas t'y connecté ou que tu as perdu la connection ?

JV
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008

Ben plus concrètement la machine reboot ou en tout cas n'est pas connecté au réseau

ZedMaTriX
Messages postés
14
Date d'inscription
vendredi 27 janvier 2006
Statut
Membre
Dernière intervention
16 juin 2009

Ce que tu peux faire c'est
Crée un tableau de socket,
lance des threads pour effectuer les connections.
aprés chaque tentative te connection tu peux faire un usleep, histoire de ne pas bourinner sur le serveur au quel tu veux te connecté.
Tu peux ensuite passé par select pour monitorer tes socket, c'est même trés recommendé.
Petit truc : pense à verouiller les sockets tant qu'elles ne sont pas connecté. Pour cela utilise des mutex (je ne suis pas sûr de l'orthographe).
Normalement ça devrait donnée un truc de pas trop mal
JV
Messages postés
178
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
14 août 2008

Vérouiller les sockets ??
Qu'entend tu par la ?

ZedMaTriX