Flux rss
Rechercher : dans
Par : Mots clés Nom d'utilisateur
Messages sans réponse

[C] [Socket] Temps limite d'un connect()

kilian, le vendredi 21 octobre 2005 à 02:16:30 
 Signaler ce message aux modérateurs

Bonsoir,

Alors voilà mon soucis,
J'ai un socket qui se connecte en tcp sur une machine distante mais au moment où la fonction connect() s'execute, le programme est en attente et la suite ne s'execute pas avant quelques minutes.

Mais tout ce que j'aimerais faire c'est lancer une tentative de connexion. Que ça réussise ou non, ça importe peu. Donc est ce qu'il est possible de fixer un temps limite pour la connexion?

J'ai pensé à lancer le connect() dans un thread mais il y a peut être d'autres solutions moins lourdes....

Configuration: Debian
Gcc

1

crabs, le vendredi 21 octobre 2005 à 08:38:53
  • +2

Salut,
Tu peux passer par via la gestion signal alarm et l'utilisation de setjmp/longjmp
Si la résolution de ton timeout est la seconde regardes du coté de alarm,
si tu cherches la milliseconde, regarde du coté de setitimer.
Le problème de connect c'est qu'il est 'restartable' dans la reception des
signaux, donc il faut utiliser setjmp/longjump.
Je te files un code C qui permettait de faire ce genre de truc.

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>

jmp_buf timeout_jump ;
void timeout(int sig)
    {
    printf( "signal %d occurs\n", sig ) ;
    longjmp( timeout_jump, 1 ) ;
    }
/***
**** timeout serveur port timeout
**** Attention pas de verification de la ligne de commande
**** le process retourne :
****   - 0 : tout est ok
****   - 1 : erreur systeme
****   - 2 : timeout
***/
int main( int argc, char** argv )
    {
    int fd, ret ;
    struct sockaddr_in sin ;
    struct hostent* host ;
    struct servent* sp  ;

    fd = socket( AF_INET, SOCK_STREAM, 0 ) ;
    if ( fd == -1 ) { perror( "socket" ) ; return 1 ; }

    host = gethostbyname( argv[1] ) ;
    if ( !host ) { perror( "gethostbyname" ) ; return 1 ; }

    sp = getservbyname( argv[2], "tcp" ) ;
    if ( !sp ) { perror( "getservbyname" ) ; return 1 ; }

    sin.sin_port = sp->s_port ;
    memcpy( &(sin.sin_addr.s_addr), (char *)host->h_addr, host->h_length ) ;
    sin.sin_family = AF_INET ;

    // on arme le timeout
    signal( SIGALRM, timeout ) ;
    alarm( atoi(argv[3] ) ;
    if ( setjmp( timeout_jump ) == 1 ) // c'est un timeout
        {
        printf( "C'est un timeout\n" ) ;
        close(fd) ;
        return 2 ;
        }
    else
        {
        ret = connect(fd,(struct sockaddr *)&sin,sizeof(struct sockaddr_in)) ;
        if ( ret == -1 )
            {
            perror( "connect()" ) ;
            alarm(0) ;
            close(fd) ;
            return 1 ;
            }
        }
    alarm(0) ;
    close( fd ) ;
    return 0 ;
    }


A+, bon courage, crabs ..., I think Slackware sounds better than 'Microsoft,'
-- Patrick Volkerding - founder and maintainer of Slackware

Répondre à crabs

2

kilian, le vendredi 21 octobre 2005 à 12:32:39

Merci crabs, je regarde tout ça ce soir :-)

Répondre à kilian

3

kilian, le vendredi 21 octobre 2005 à 21:05:30
  • +1

Ok j'ai enfin compris le système des setjmp et longjmp combinés avec alarm.

Merci beaucoup pour le code :-)
Au fait c'est normal que lorsque mon socket se connecte à un port sur une adresse (avec connect() ), l'application reste en attente comme ça?
Ca me fait ça que le port soit masqué ou en écoute.....

Avec netstat j'ai ce statut affiché: SYN_SENT
Et ça n'évolue pas.
En gros je n'ai pas de réponse de l'application serveur (testé avec postfix et vsftpd).... Et ce n'est pas un soucis de Firewall...

C'est la première fois que j'utilise les sockets.

Répondre à kilian

4

crabs, le vendredi 21 octobre 2005 à 21:24:17
  • +2

Salut,

Etat SYN_SENT : la demande de connection est partie, le socket est
alors en attente de réponse (ACK).
Il peut y avoir 4 raisons :
- le système ne sait pas atteindre la machine distante, ça arrive souvent quand
on demande une adresse privé en s'adressant à une passerelle publique sans
tunneling
- le système ne sait pas répondre au serveur : il ne connait pas la route pour
assurer le retour de la réponse, ça arrive souvent si la machine locale à une
adresse privée et qu'elle n'est pas derrière une masquarade, ou alors la
machine distante est mal configurée pour le routage.
- le système distant fait un DROP du paquet ou tout dispositif de type firewall
entre la machine locale et la machine distante.
- la machine locale fait un DROP sur la réponse ou tout dispositif de type
firewall entre la machine distante et la machine locale permettant d'assurer
le retour de la réponse

Des outils de types ethereal ou iptraf peuvent te donner plus d'info sur la
raison de la non-réponse.
A+, crabs ..., I think Slackware sounds better than 'Microsoft,'
-- Patrick Volkerding - founder and maintainer of Slackware

Répondre à crabs

5

 kilian, le samedi 22 octobre 2005 à 04:50:09
  • +1

Ok je crois avoir trouvé finalement.

J'étais sûr de mes règles de firewall mais en fait....tu as raison mon firewall fait un DROP.
En fait j'essayais de me connecter depuis mon adresse publique sur mon adresse publique (même source et destination).
Je ne sais pas pourquoi mais mon firewall n'accepte probablement pas la réponse (ou la demande...).

Bon ben c'est réglé... Merci pour tout :-)

Répondre à kilian
Limiter le temps de connexion Bonjour tout le monde j'ai une connexion Free 50h ( PC, win98SE avec carte modem intègrè ) et je cherche un logiciel pour limiter le temps de connexion dans une journée . Exemple temps de connexion maxi 2h par jour, au bout des 2h le modem est... www.commentcamarche.net/forum/affich-184668-limiter-le-temps-de-connexion
[Thunderbird] Temps limite dépassé J'utilise Thunderbird 2.0.0.6. sous Windows XP Pro. Je relève ma messagerie (gmail) par POP. Utilisation intensive sans aucun problème jusqu'à il y a quelques jours. Depuis peu j'obtiens un message d'erreur "Temps limite dépassé lors de la connexion... www.commentcamarche.net/forum/affich-3582398-thunderbird-temps-limite-depasse
Temps limite dépassé pour réception messages Bonjour, depuis quelques temps, mais pas à chaque fois, ma messagerie Thunderbird sort le message suivant: temps limite dépassé pour la connexion au serveur pop3.J'ai vérifié les paramétres de mon compte, tout semble bon. Quelqu'un pourrait-il m'aider... www.commentcamarche.net/forum/affich-11608897-temps-limite-depasse-pour-reception-messages
Comment contrôler les temps de connection surBonjour à tous, Comment faire pour voir le temps ou les temps de( connection et deconnection). Je suis chez FREE!!!! Merci à vous. Laure www.commentcamarche.net/forum/affich-9493915-comment-controler-les-temps-de-connection-sur
Probleme C:\Windows\TEMP\logishrd\LVPrcInj01.Bonjour, mon antivirus me met un message d'alerte à propos d'un fichier qui se trouve là: C:\Windows\TEMP\logishrd\LVPrcInj01.dll impossible de le déseinstaller... www.commentcamarche.net/forum/affich-12240148-probleme-c-windows-temp-logishrd-lvprcinj01
Limitation temps de connection internet (Résolu)Bonjour à tous! Après quelques recherches infructueuses, je m'en remet à vous :). Je cherche un moyen de limiter le temps de connection de mon fils qui passe ses journées à jouer sur Counter Strike. Le dialogue a fait son effet pendant un moment mais... www.commentcamarche.net/forum/affich-3191039-limitation-temps-de-connection-internet
Les fonctions de l'API SocketLes fonctions des sockets en détail La fonction socket() La création d'un socket se fait grâce à la fonction socket() : int socket(famille,type,protocole) famille représente la famille de protocole utilisé (AF_INET pour TCP/IP utilisant une... www.commentcamarche.net/contents/sockets/sockfonc.php3