IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

TCP/IP , information de connexion rompue


Sujet :

Réseau C

  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Par défaut TCP/IP , information de connexion rompue
    Bonjour,

    je développe actuellement une application utilisant une connexion TCP/IP et je suis confronté à un problème assez ennuyeux.

    Je situe :

    mon application doit dialoguer avec un appareil en protocole ARINC-485. Ce protocole est assez simple, si s'agit d'un mode de question / reponse , 1 question du master (mon application) , et 1 réponse et 1 seule du Slave (l'appareil en question). Lorsque je ne dois pas interroger l'appareil, je dois envoyer une commande "IDLE" , et ce , toutes les secondes.

    Ce dialogue se fait en RS485 mais mon application se trouve sur un matériel embarqué ne possédant qu'une interface TCP/IP. j'ai donc connecté un appareil qui convertit du TCP/IP en RS afin de faire le relais.

    Du coup, mon dialogue question/ reponse se fait non plus en RS485 mais en TCP/IP.

    l'algo intuitif qui vient alors est le suivant : (je ne mets pas le code il est assez enorme).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    while (connexion) {
         // verifier la pile de message en attente. Si elle est vide, y ajouter un message IDLE.
     
        send(socket,prochain_message,len,0);
     
         //  puis derriere 
     
        recv(socket,data,1024,0);   
     
    }
    Seulement, ce code ne convient pas car il peut arriver que je ne recoive pas de données , et vu que la fonction recv est bloquante , je bloquerait indéfiniment sur cette fonction ce qui est inenvisageable.

    La solution apportée est la suivante,plutot que de rendre non bloquante la fonction recv, je la laisse bloquante, et je me sers de la fonction select afin d'attendre l'éventuelle arrivée de données sur la socket, et les lire seulement s'il y a des données présentes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
     while (connexion) {
      // verifier la pile de message en attente. Si elle est vide, y ajouter un message IDLE.     
     
      send(socket,prochain_message,len,0);
      struct timeval t;
      t.tv_sec = 1;
      t.tv_usec = 0; // 1000ms de timeout
      fd_set ensemble;
      FD_ZERO(&ensemble);
      FD_SET(m_socket,&ensemble);
      valret = select(socket+1, &ensemble, 0, 0, &t);
    if (valret == SOCKET_ERROR){
        NetworkError("select" );
    }        
    if(FD_ISSET(m_socket,&ensemble)!=0) { // des données sont recues
        valret = recv(socket,data,1024,0);
     if (valret== SOCKET_ERROR)  {
    NetworkError("receive" );                
        }
      } 
     }
    L'algo donne donc :

    - j'envoie des données.
    - j'attends 1 seconde si des données sont arrivées.
    - Si des données sont arrivées , je les lis.

    Seulement, il arrive parfois (et c'est un fonctionnement normal), que certains appareils (le convertisseur TCP/IP-RS ou l'appareil distant) soient mis hors tension , ce qui a pour conséquence de rompre la connexion TCP/IP.

    Hors, je n'ai pas l'indication que la connexion est rompue puisque par défaut, je ne fais que des send.


    Voici un extrait du man send :

    Aucune indication d'échec de distribution n'est fournie
    par send. Seules les erreurs locales sont détectées, et
    indiquées par une valeur de retour -1.
    Je ne peux donc pas utiliser la valeur de retour pour tester une erreur de connexion rompue, puisque seules les erreurs locales sont détectées.

    Par contre, recv me renvoie bien une erreur des que la connexion est rompue mais l'appel ne peut pas passer a cause de la facon dont est fait l'algo ( je ne fais appel a recv que s'il y a des données recues, et il ne peut pas en avoir puisque la connexion est rompue).

    Je n'ai donc que 2 fonctions qui sont appelées quand je suis dans cet état là :
    - send , avec laquelle je ne peux pas gérer cette erreur.
    - select : apparemment cette fonction ne retourne pas non plus d'erreur lorsque la connexion est rompue.

    Je n'arrive pas à voir de solution à mon problème , et je ne sais pas comment détecter qu'une connexion a été rompue (autrement qu'avec un appel à recv).

    Quelqu'un peut il m'éclairer à ce sujet ou dois-je revoir totalement mon algo ?


    merci d'avance

  2. #2
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Lorsque la connexion est rompue select est declenché, et le recv retourne -1 (enfin je suppose car sous Linux, avec la fonction read c'est comme ca que ca se passe).

    Essaye quand meme.

  3. #3
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Par défaut
    je suis bien sous linux, et il me semble que select ne passe pas. Je refais un test et je viens afficher les logs.

  4. #4
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Par défaut
    hum, j'ai peur que ca ne fonctionne pas

    mon code est portable sous windows et sous linux.

    Voici le log quand je suis sous windows :

    Select : valeur de retour : 1
    Receive STV : F9 9C 6A
    Info : receive IDLE message
    Airshow : NORMAL call
    Airshow : request Status Request
    Try to send (3) (3)bytes
    Select : valeur de retour : 1
    Receive STV : F9 9C 6A
    Info : receive IDLE message
    Write serial 00 00 19 51 19 51 03 10 00 00 00 00 00 00 03 15
    Airshow : NORMAL call
    Airshow : request Status Request
    Try to send (3) (3)bytes
    Select : valeur de retour : 1
    Receive STV : F9 9C 6A
    Info : receive IDLE message
    Airshow : NORMAL call
    Airshow : request Status Request
    Try to send (3) (3)bytes
    <<<<<<< JE SIMULE ICI L ARRET DE LA MACHINE>>>>>>>>>>>>
    Select : valeur de retour : 0
    Airshow : request Status Request
    Try to send (3) (3)bytes
    Select : valeur de retour : 0
    Airshow : request Status Request
    Try to send (3) (3)bytes
    Select : valeur de retour : 0
    Airshow : request Status Request
    Try to send (3) (3)bytes
    Select : valeur de retour : 0
    Airshow : UNINITIALIZED call
    Airshow : request PUS
    Try to send (12) (12)bytes
    Select : valeur de retour : 0
    Airshow : UNINITIALIZED call
    Airshow : request PUS
    Try to send (12) (12)bytes
    Select : valeur de retour : 0
    Airshow : UNINITIALIZED call
    Airshow : request PUS
    Try to send (12) (12)bytes
    Select : valeur de retour : 0
    Airshow : UNINITIALIZED call
    Airshow : request PUS
    Try to send (12) (12)bytes
    Select : valeur de retour : 0
    Airshow : UNINITIALIZED call
    Airshow : request PUS
    Try to send (12) (12)bytes
    Select : valeur de retour : 0
    Airshow : UNINITIALIZED call
    Airshow : request PUS
    Try to send (12) (12)bytes
    Select : valeur de retour : 0
    Airshow : UNINITIALIZED call
    Airshow : request PUS
    Try to send (12) (12)bytes
    Select : valeur de retour : 0
    Write serial 00 00 0F 23 0F 23 83 00 A0 02 58 00 00 00 05 19
    Airshow : UNINITIALIZED call
    Airshow : request PUS
    Try to send (12) (-1)bytes
    <<<<<<<<<<<< JE RECOIS UNE VALEUR DE RETOUR DE LA PART DE SELECT >>>>>>>>>>>>>>
    Select : valeur de retour : 1
    Network Error : (CTouchLiveTV). Error : 10054 (receive)
    Airshow : CONNECTION LOST call
    Error : Can't connect to address 172.16.201.1 port 4001 for LIVETV
    Airshow : CONNECTION LOST call

    Avant la coupure, la fonction select me renvoie bien la valeur 1, ce qui signifie qu'il y a des données à lire sur une des sockets de mon ensemble (c est a dire, ma socket vu que je n'en ai spécifié qu'une seule).

    Lorsque je simule la coupure, select me renvoie bien 0 vu qu'il n'y a plus de données à lire (je ne peux plus en recevoir, mon appareil est coupé).

    Au bout d'un moment, select me renvoie à nouveau 1, ce qui me permet de passer la ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if(FD_ISSET(m_socket,&ensemble)!=0) { // des données sont recues
                len= recv(m_socket,data,1024,0);
                if (len == (DWORD)SOCKET_ERROR)  {
                    NetworkError("receive");                
                    return LIVETV_CONNECTIONLOST;
                }
            }
    et ainsi passer dans le recv, qui lui, me renvoie une erreur SOCKET_ERROR.


    Seulement, sous linux ca ne fonctionne pas pareil, le select me renvoie toujours 0 (j'ai laissé tourner pendant 10mn apres ma coupure, et ca ne change rien).

    Ai je mal initialisé mon select ?

    voici le code exact que j'utilise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    t.tv_sec = 1;
            t.tv_usec = 0; // 1000ms de timeout
            fd_set ensemble;
            FD_ZERO(&ensemble);
            FD_SET(m_socket,&ensemble);
            do {
                valret = select(m_socket+1, &ensemble, 0, 0, &t);
                Log(LOGLEVEL_SYSTEM,"Select : valeur de retour : %d",valret);
            } while (valret == SOCKET_ERROR && SocketErrno == EINTR);
     
            if (valret == SOCKET_ERROR){
                NetworkError("select");
                return LIVETV_CONNECTIONLOST;
            }
     
            if(FD_ISSET(m_socket,&ensemble)!=0) { // des données sont recues
                len= recv(m_socket,data,1024,0);
                if (len == (DWORD)SOCKET_ERROR)  {
                    NetworkError("receive");                
                    return LIVETV_CONNECTIONLOST;
                }
            }
     
            else // si timeout ecoulé , alors return NACK
            {
               if (m_dwIdxTrame == 0) 
                   return LIVETV_NORESPONSE;
               else
                   return LIVETV_BADCHECKSUM;
            }

    sachant que je n'utilise qu' une socket, j'ai initialisé le parametre 0 de la fonction select à m_socket+ 1 (m_socket etant la valeur de ma socket).
    Ce parametre est ignoré sous windows mais pas sous linux.


    Je ne comprends pas pourquoi le fonctionnement est différent sous windows et sous linux ?


    merci

  5. #5
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Je viens de regarder l'un de mes codes et voila la igne que j'avais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if((lu=read(S.sock, buf, sizeof(buf))) <= 0) {
    /* deconnexion d'un client */
    }

  6. #6
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Par défaut
    Oui, je sais que l'erreur se produira sur un recv (ou read). Seulement , j'ai mon appel a select qui m'en empeche.

    Sous windows le select me renvoie 1 au bout de 30sec ce qui me permet de faire ensuite mon appel a recv qui me renverra -1.
    Sous linux, le select me renvoie tout le temps 0 , et ce, pendant 10mn, comme si la connexion existait toujours (alors qu'elle est bien rompue j'ai débranché le cable reseau pour simuler, et egalement éteint les appareils).

    Le comportement est différent et je ne vois pas pourquoi puisque c'est le meme code pour les 2.

  7. #7
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Par défaut
    je viens de detailler un peu plus le processus :


    sous windows, lorsque je coupe la connexion, select me renvoie 0 (normal, pas de données sur la socket), et au bout d'environ 30 sec , le select me renvoie 1, ce qui me permet de passer dans le recv , et la fonction recv me renvoie -1 . Du coup, je peux rétablir ma connexion vu que je sais qu'elle est coupée.

    Sous linux, je viens de logguer pendant 15mn, lorsque je coupe la connexion, select me renvoie 0 pendant 15mn (1 appel a select par seconde pendant 15mn). Puis au bout de délai, select me renvoie 1, mon appel a recv peut donc etre effectué, mais cette fois-ci, il ne me renvoie pas -1 , pour me dire qu'il y a une erreur, mais la valeur 0 , comme si rien n'a été recu.

    le fait que l'état change au bout de 30 sec sous windows et 15mn sous linux (debian woody 3.0, avec noyau 2.4.20 , le controleur ethernet est une puce de type RTL8139) , ressemble a un timeout de connexion... mais 15mn je trouve ca enorme, est il possible de parametrer ce genre de chose ?

    Par contre, ce que je trouve anormal, et je ne comprends pas pourquoi ca fait ca , c'est que mon appel à select me renvoie 1, ce qui est censé signifier que l'état de la socket a changé (donc des données ont été recues , ou peut etre autre chose ?) , mais recv ne me renvoie pas d'erreur, seulement la valeur 0.

    Que dois-je en conclure ? que j'ai fait une erreur, ou bien que pour tester la rupture de ma connexion, c'est un recv qui renvoie 0 après un select qui passe bien ?

    merci

  8. #8
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Moi j'avais fait un chat sous Linux, et lorsqu'un client se deconnectait sur serveur, le select se declanchait de suite.

    De plus pourquoi mes tu un timeout à ton select, je n'ai pas compris a quoi cela servait.

    Si tu veux voir mon code (C++) regarde dans ma signature, le truc qui s'appelle PussyChat

  9. #9
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Par défaut
    Citation Envoyé par Skyrunner
    Moi j'avais fait un chat sous Linux, et lorsqu'un client se deconnectait sur serveur, le select se declanchait de suite.

    De plus pourquoi mes tu un timeout à ton select, je n'ai pas compris a quoi cela servait.

    Si tu veux voir mon code (C++) regarde dans ma signature, le truc qui s'appelle PussyChat

    le timeout sur le select sert a rendre la fonction bloquante mais dans un temps limité.

    une valeur nulle rendrait la fonction select bloquante indéfiniment, ce n'est pas ce que je recherche.


    De ton coté , si ca se déclenchait tout de suite, c'est simplement parce que tu avais une fermeture normale de la connexion. Ce n'est pas mon cas, je dois prendre en compte toutes les ruptures possibles (y compris le cable réseau débranché). Et avec le meme code, ca ne fonctionne pas sur ma plateforme linux, alors que ca fonctionne sous windows.


    Je vais egalement tester sur une version plus récente de linux pour voir si ca vient de la.

  10. #10
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Mon programme marchait avec un Ctrl+C realisé sur le client, la connexion etait correctement fermée sur le serveur, hors un Ctrl+C n'est pas une fermeture normal d'un programme...

  11. #11
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Par défaut
    pour affirmer ce que je dis , voici un code qui fonctionne parfaitement sous windows, et qui ne marche pas sous linux.

    Comportement : je lance ce code sous windows, lorsque je romps la connexion en débranchant le cable, j'ai mon select qui renvoie 1 presque instantanément ce qui me permet de faire un appel à recv et quitter mon programme.

    Le meme code (un peu adapté pour compiler) sous linux ne fonctionne pas. C'est à dire que le programme boucle comme si la connexion fonctionnait toujours, et ce , pendant plus de 10mn.

    J'ai essayé le code sur 2 linux différents : debian woody 3.0 glibc 2.2, et mandriva 2006 avec glibc 2.3, aucun changement.


    voici le code (version linux) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
     
    int main()
    {
        int s=-1;        
        struct sockaddr_in localaddr;
     
        s = socket(PF_INET,SOCK_STREAM,0);
     
        if (s == -1 ) {
            printf("Erreur : creation socket\n");
            return 0;        
        }
     
        // ensuite remplir la structure
        localaddr.sin_family = PF_INET;
        localaddr.sin_addr.s_addr = inet_addr("172.16.201.1");
        localaddr.sin_port = htons(4002);
     
        // se connecter
        if (connect(s,(struct sockaddr *)&localaddr,sizeof(localaddr)) == -1) {
            printf("Erreur : ne peut pas se connecter à l'adresse 172.16.201.1 sur le port 4002.\n");
            close(s);
            return 0;
        }
     
     
     
        char buffer[4]; // envoi en entrée 01020304
        char data[4]; // reception
     
        buffer[0] = 0x01;
        buffer[1] = 0x02;
        buffer[2] = 0x03;
        buffer[3] = 0x04;
        data[0] = 0x00;
        data[1] = 0x00;
        data[2] = 0x00;
        data[3] = 0x00;
     
        while (data[0] != (char)0xFF || data[1] != (char)0xFF || data[2] != (char)0xFF || data[3] != (char)0xFF) {
            struct    timeval t;
            fd_set    ensemble;
            int    ret;
     
            t.tv_sec = 1;
            t.tv_usec = 0;        
            FD_ZERO(&ensemble);
            FD_SET(s,&ensemble);
     
     
     
            ret = send(s,buffer,4,0);
            printf("Ecrit 4 octets sur socket, (%d) reellement ecrit\n",ret);
            ret = select(s+1,&ensemble,0,0,&t);
            printf("Appel à la fonction select qui attend pendant 1 sec : valeur de retour :%d\n",ret);
     
            if (ret == -1) {
                printf("Recu la valeur -1 sur un select, correspond à une erreur système. Fermeture de la connexion et du programme\n");
                close(s);
                return 0;            
            }
            if(FD_ISSET(s,&ensemble)!=0) { // des données sont recues
                ret= recv(s,data,4,0);
                if (ret == -1 )  {
                    printf("Recu la valeur -1 sur un appel à receive. Signifie que la connexion n'existe plus. Fermeture de la connexion et du programme.\n");
                     close(s);    
                    return 0;                
                }
                else {            
                    printf("Recu %d octets en ayant demandé de lire 4 octets.\n",ret);
                }
            }
        }
        close(s);
        return 0;
    }


    Le code est minimal et ne comporte aucune erreur à mon avis.

    Je n'ai plus le temps ce soir d'écrire un mini serveur pour simuler sur une meme machine ou 2 machines distinctes, mais je ferai ca demain.

  12. #12
    Membre éprouvé
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Par défaut
    Citation Envoyé par man recv
    RETURN VALUE
    These calls return the number of bytes received, or -1 if an error
    occurred. The return value will be 0 when the peer has performed an
    orderly shutdown.
    je ne sais pas ou tu prend ta doc, mais chez moi c'est ecrit en toute lettres, recv renvois 0 lorsque la connexion est interrompu.

  13. #13
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Skyrunner
    Mon programme marchait avec un Ctrl+C realisé sur le client, la connexion etait correctement fermée sur le serveur, hors un Ctrl+C n'est pas une fermeture normal d'un programme...
    Non, mais ton systeme devait certainement clore plus ou moins correctement la connexion TCP/IP (avec un RST je pense) lorsque le programme client etait interrompu, meme de maniere brutale.
    Ce qui n'est pas le cas si tu debranche le cable reseau ou le cable d'alimentation du client.

  14. #14
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Par défaut
    Citation Envoyé par Dark_Ebola
    je ne sais pas ou tu prend ta doc, mais chez moi c'est ecrit en toute lettres, recv renvois 0 lorsque la connexion est interrompu.

    Salut

    la fatigue m'a fait louper la fin de cette phrase ... effectivement j'avais pas vu. Surement parceque j'ai regardé par reflexe dans la doc msdn , ou sur un site internet dans lequel ca n'était pas précisé explicitement.
    Merci bien de m'avoir apporté cette précision.

    Par contre, je ne sais toujours pas pourquoi la rupture de connexion apparait si tardivement. Ca peut mettre 10-15mn avant que le select s'apercoive d'un changement sur la socket et evidemment c'est innacceptable pour mon application puisque je dois reconnecter derrière dès que l'appareil distant est de nouveau disponible (30sec d'attente est acceptable).

    Est ce que cette donnée est parametrable ou ca depend de l'implémentation du système ?

    merci

  15. #15
    Membre éprouvé
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Par défaut
    j'ai fait ma tite enquete ... (j'ai appris un truc comme ça)
    setsockopt as l'air d'etre ce que tu cherche.
    sous Linux//Unix:
    #include <sys/socket.h>
    int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len);


    sous windows: http://msdn.microsoft.com/library/de...tsockopt_2.asp


    et il faut utiliser(nux):
    SO_RCVTIMEO Sets the timeout value that specifies the maximum amount of time an input function waits until it completes. It accepts a timeval structure with the number of seconds and microseconds specifying the limit on how long to wait for an input operation to complete. If a receive operation has blocked for this much time without receiving additional data, it shall return with a partial count or errno set to [EAGAIN] or [EWOULDBLOCK] if no data is received. The default for this option is zero, which indicates that a receive operation shall not time out. This option takes a timeval structure. Note that not all implementations allow this option to be set.
    win:
    SO_RCVTIMEO and SO_SNDTIMEOWhen using the recv function, if no data arrives during the period specified in SO_RCVTIMEO, the recv function completes. In Windows versions prior to Windows 2000, any data received subsequently fails with WSAETIMEDOUT. In Windows 2000 and later, if no data arrives within the period specified in SO_RCVTIMEO the recv function returns WSAETIMEDOUT, and if data is received, recv returns SUCCESS.If a send or receive operation times out on a socket, the socket state is indeterminate, and should not be used; TCP sockets in this state have a potential for data loss, since the operation could be canceled at the same moment the operation was to be completed.
    les docs c'est utile, il faut les lire

  16. #16
    Membre confirmé
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Par défaut
    je teste ca demain matin et je te dis si ca marche merci en tout cas.

    PS : c est pas que je veux pas les lire les docs ^^ mais je cherche jamais au bon endroit

Discussions similaires

  1. [Débutant] Passage d'informations à la connexion sockets
    Par bobylastar49 dans le forum C#
    Réponses: 6
    Dernier message: 13/12/2012, 13h40
  2. Réponses: 4
    Dernier message: 31/03/2011, 10h49
  3. Réponses: 4
    Dernier message: 05/03/2010, 11h15
  4. [BO 5.1.8] Rafraîchir les informations de connexion
    Par greg543 dans le forum Administration-Migration
    Réponses: 14
    Dernier message: 22/11/2007, 23h31
  5. Enregistrer les informations de connexion client RDP
    Par genialk2000 dans le forum Autres Logiciels
    Réponses: 1
    Dernier message: 31/01/2006, 17h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo