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 :

[socket & windows & accept]


Sujet :

Réseau C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juin 2003
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Juin 2003
    Messages : 25
    Points : 20
    Points
    20
    Par défaut [socket & windows & accept]
    Bonjour à tous !

    après une recherche sur ce forum, j'ai trouvé quelques sujets qui touchent a mon probleme (http://www.developpez.net/forums/vie...=socket+accept) mais qui ne le traitent pas vraiment...

    Je bosse avec un ami sur un client tcp/ip sous windows et je souhaite gérer le time out au serveur : lors de l'accept du serveur.
    J'essaie de faire en sorte qu'au bout de X secondes, si le client ne s'est pas connecté, le serveur quitte.
    Jusqu'à présent je travaillais avec des socketes bloquantes , donc on restait sur l'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sock3 = accept(sock2, (struct sockaddr*)&mytcp,&len);
    J'ai essayé de changer la nature de la socket pour incorporer le time out

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    u_long val = 0;
    ioctlsocket(sock3,FIONBIO,&val); 
    printf("[*] waiting for shell\n");
    timeout = 500;
    endtime=(clock_t) (((double) timeout)/1000)*CLOCKS_PER_SEC + clock(); 
    sock3=INVALID_SOCKET
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    do 
    {
      sock3 = accept(sock2, (struct sockaddr*)&tcp,&taille); 
      printf("..");
      fflush(stdout);
    }
     while(sock3==INVALID_SOCKET && endtime>clock());
    apres test, sock3 est bien différent de invalid, car on sort de la boucle (et que le temps n'est pas ecoulé, j'ai fais une verif). Mais le client ne s'est pas connecté !
    donc pourquoi change t'il de valeur ? j'ai essayé de remplacer INVALID_SOCKET par SOCKET_ERROR , on sort quand meme de la boucle, immédiatement.
    S'il faut que je rechange ma socket en bloquante, alors peut on gérer le time out en bloquant ?

    (je sais qu'avec ma boucle et cette socket non bloquante je vais allégrement puiser dans les ressources machines )

    merci de vos réponses

  2. #2
    Membre à l'essai
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juin 2003
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Juin 2003
    Messages : 25
    Points : 20
    Points
    20
    Par défaut
    y a t'il une possibilité en passant par un select ?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 21
    Points : 24
    Points
    24
    Par défaut
    Oui le select est la reponse a ta question et permet de gerer bien plus facilement que ioctl le probleme de fonctions bloquantes sur les serveurs.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juin 2003
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Juin 2003
    Messages : 25
    Points : 20
    Points
    20
    Par défaut
    j'ai cherché sur le select , mais rien sur la gestion du time out. Il sert seulement à surveiller des sockets ouvertes, et je n'en ai qu'une ouverte... A moins que j'ai raté un épisode ?

  5. #5
    Candidat au Club
    Inscrit en
    Avril 2004
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    On employe select() avant d'appeler accept().

    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
     
    SOCKET AcceptTimeout(SOCKET s, struct sockaddr * addr, int addrlen, long ms)
    {
    	u_long val = 0; 
    	struct timeval tv;
    	fd_set readfds;
    	int result;
     
    	tv.tv_sec  = 0;
    	tv.tv_usec = ms * 1000; // le temps d'attendre en micro-secondes
     
    	ioctlsocket(s, FIONBIO, &val);
     
    	FD_ZERO(&readfds);
    	FD_SET(s, &readfds);
     
    	// Attendre pour le socket devenir lisible
    	result = select(s + 1, &readfds, NULL, NULL, &tv);
     
    	if (result == 1 && FD_ISSET(s, &readfds)) // le socket est lisable (accept() retournera immédiatement)
    		return accept(s, (struct sockaddr*) addr, &addrlen);
    	else // le temps a ecoulé
    		return SOCKET_ERROR;
    }

  6. #6
    Membre à l'essai
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juin 2003
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Juin 2003
    Messages : 25
    Points : 20
    Points
    20
    Par défaut
    Merci beaucoup pour ce code excellent, que j'ai immédiatement testé.

    Le time out marche très bien (si mon client ne se connecte pas, mon serveur quitte au bout de x secondes), par contre j'aboutis toujours au meme probleme que lorsque je travaillais avec ma socket non bloquante : ma socket n'est pas lisible.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result = select(s + 1, &readfds, NULL, NULL, &tv);
    ceci me renvoie 0, même si mon client se connecte ...
    et forcément le accept me renvoie -1 D'où déconnection de mon serveur.
    J'ai essayé de changer readfds à writefds mais ca ne change rien, je suis toujours à 0...

  7. #7
    Candidat au Club
    Inscrit en
    Avril 2004
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    u_long val = 0; 
    ioctlsocket(sock3,FIONBIO,&val);
    La val était incorrecte! Zéro est bloquant et non zéro est non bloquant!
    Ce code travaille bien pour moi:
    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
     
    SOCKET AcceptTimeout(SOCKET s, struct sockaddr * addr, int addrlen, long ms) 
    { 
       u_long val = 1; 
       struct timeval tv; 
       fd_set readfds; 
       int result; 
     
       tv.tv_sec  = 0; 
       tv.tv_usec = ms * 1000;
     
       ioctlsocket(s, FIONBIO, &val); 
     
       FD_ZERO(&readfds); 
       FD_SET(s, &readfds); 
     
       result = select(s + 1, &readfds, NULL, NULL, &tv); 
     
       if (result == 1 && FD_ISSET(s, &readfds))
       {
          return accept(s, (struct sockaddr*) addr, &addrlen); 
       }
       else
       {
          if (result != SOCKET_ERROR) WSASetLastError(WSAETIMEDOUT);
          return INVALID_SOCKET; 
       }
    } 
     
     
    int main(void)
    {
       WSADATA wsaData;
       SOCKET serverSocket, recvSocket;
       struct sockaddr_in local  = { 0 };
       struct sockaddr_in remote = { 0 };
     
       WSAStartup(0x202,&wsaData);
     
       local.sin_family      = AF_INET;
       local.sin_port        = htons(80);
       local.sin_addr.s_addr = INADDR_ANY;
     
       serverSocket = socket(AF_INET, SOCK_STREAM, 0);
     
       bind(serverSocket, (struct sockaddr *) &local, sizeof(local));
       listen(serverSocket, SOMAXCONN);
     
       recvSocket = AcceptTimeout(serverSocket, (struct sockaddr *) &remote , sizeof(remote), 5000);
     
       if (recvSocket == INVALID_SOCKET)
       {
          printf("AcceptTimeout Erreur: %d\n", WSAGetLastError());
       }
       else
       {
          u_long val = 0;
          char buf[512];
          int cnt;
     
          printf("AcceptTimeout a réussi. Addr: %s\n", inet_ntoa(remote.sin_addr));
     
          // rechange socket en bloquant
          ioctlsocket(recvSocket, FIONBIO, &val); 
     
          cnt = recv(recvSocket, buf, sizeof(buf) - 1, 0);
     
          if (cnt > 0)
          {
              buf[cnt] = '\0';
              printf("\n%s\n", buf);
          }
          else
          {
              printf("recv Erreur: %d\n", WSAGetLastError());
          }
       }
     
       getchar();
       return 0;
    }

  8. #8
    Membre à l'essai
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juin 2003
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Juin 2003
    Messages : 25
    Points : 20
    Points
    20
    Par défaut
    j'ai trouvé mon erreur, et ce code est adapté pour réponde à mon probleme.
    J'en profite pour dire que le s+1 dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result = select(s + 1, &readfds, NULL, NULL, &tv);
    n'avais aucune incidence (on aurait pu mettre n'importe quoi, cf msdn)

    merci encore !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. socket c++ windows/linux
    Par magic.goby dans le forum C++
    Réponses: 6
    Dernier message: 19/07/2005, 23h43
  2. Socket sous windows
    Par Higestromm dans le forum Windows
    Réponses: 20
    Dernier message: 11/01/2005, 17h47
  3. utilisation des sockets sous windows
    Par Tupac dans le forum Réseau
    Réponses: 2
    Dernier message: 21/12/2002, 18h24

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