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 :

serveur TCP multi-clients threadé


Sujet :

Réseau C

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 11
    Par défaut serveur TCP multi-clients threadé
    Bonjour,
    je dois réaliser un serveur TCP multi-clients avec des threads mais mon programme ne fais rien et attends a l'infini. Voici le code :

    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <netdb.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <pthread.h>
    # include <signal.h>
    #include <time.h>
    #include "SHM.c"
     
    #define TAILLEBUF 20
     
     
     
    void * fn_thread ( void * c )
    {
     
    printf("ici");
    }
     
     
    pthread_t thread[NB_THREAD];
     
    int main(int argc, char *argv[]) {
     // adresse socket coté client
      static struct sockaddr_in addr_client;
      // adresse socket locale
      static struct sockaddr_in addr_serveur;
      // longueur adresse
      int lg_addr;
      // socket d'écoute et de service
      int socket_ecoute, socket_service;
      // buffer qui contiendra le message reçu
      char message[TAILLEBUF];
      // chaîne reçue du client
      char *chaine_recue;
      // chaîne renvoyée au client
      char *reponse = "bien recu";
      // nombre d'octets reçus ou envoyés
      int nb_octets;
     
      // création socket TCP d'écoute
      socket_ecoute = socket(AF_INET, SOCK_STREAM, 0);
      if (socket_ecoute == -1) {
              perror("creation socket");
              exit(1); }
      // liaison de la socket d'écoute sur le port 4000
      bzero((char *) &addr_serveur, sizeof(addr_serveur));
      addr_serveur.sin_family = AF_INET;
      addr_serveur.sin_port = htons(4000);
      addr_serveur.sin_addr.s_addr=htonl(INADDR_ANY);
      if( bind(socket_ecoute,
                    (struct sockaddr*)&addr_serveur,
                    sizeof(addr_serveur))== -1 ) {
              perror("erreur bind socket écoute");
              exit(1);
      }  // configuration socket écoute : 5 connexions max en attente
     
      if (listen(socket_ecoute, 5) == -1) {
            perror("erreur listen");
            exit(1);
      }
     
    int compteur=0;
     
    		while(1){
     
     		lg_addr = sizeof(struct sockaddr_in);
    		   socket_service = accept(socket_ecoute,
    			      (struct sockaddr *)&addr_client,
    		  &lg_addr);
     
    				  if (socket_service == -1) {
    					perror("erreur accept");
    					exit(1);
    				  }
    	       int creation_thread=pthread_create(&thread[compteur],NULL,fn_thread,(void *)socket_service);
    									if(creation_thread!=0)
    									{
    									perror("pthread_create");
    									}
     
    			compteur++;				
    			close(socket_service);
     
     
     
     
     
    			}
    close(socket_ecoute);
    }
    Pouvez vous m'aider merci.

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Déjà il convient de supprimer ceci : Après, si tu ajoute fflush(stdout) après printf("ici"), tu verras que ton serveur fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void * fn_thread ( void * c )
    {
        printf("ici");
        fflush(stdout);
        return NULL;
    }
    Je me connecte avec putty trois fois de suite :

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 11
    Par défaut
    J'ai rajouté ce que tu as mis et ca marche , cela affiche bien "ici" des qu'un client se connecte . Merci beaucoup pour ta rapidité et ton aide Mabu.

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 11
    Par défaut
    J'ai rajoute un read dans le corps du thread :

    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
     
     
    void * fn_thread ( void * c )
    {
    int socket_service=(int)(c);
    printf("ici");
     
     int nb_octets;
      // la connexion est établie, on attend les données envoyées par le client
      int nombre;
      nb_octets = read(socket_service, &nombre,
      sizeof(nombre));
      printf("%d",nombre);
     
    fflush(stdout);
    return NULL;
     
     
    }
    mais le read n'attend pas de donnees , il affiche directement 0 avec le printf . Le client fonctionne bien.

  5. #5
    Invité(e)
    Invité(e)
    Par défaut
    Et que vaut nb_octets ?
    Comment est envoyé le nombre depuis le client ?

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 11
    Par défaut
    Salut ,
    nb_octets retourne -1 et le client a été testé avec un serveur simple qui retourne bien la valeur. Voici le code si tu veux voir :

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <netdb.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
     
    #define TAILLEBUF 20
     
    int main(int argc, char *argv[]) {
     
      // identification socket d'écoute du serveur
      static struct sockaddr_in addr_serveur;
      // identifiants de la machine où tourne le serveur
      struct hostent *host_serveur;
      // socket locale coté client
      int sock;
      // message à envoyer au serveur
      char *message = "bonjour";
      // chaîne où sera écrit le message reçu
      char reponse[TAILLEBUF];
      // nombre d'octets envoyés/reçus
      int nb_octets; 
     
      // vérification des paramètres du programme
     
      // création socket TCP
      sock = socket(AF_INET, SOCK_STREAM, 0);
      if (sock == -1) {
        perror("creation socket");
        exit(1); }
     
      // récupération identifiants de la machine serveur
      host_serveur = gethostbyname("127.0.0.1");
      if (host_serveur==NULL)  {
        perror("erreur récupération adresse serveur\n");
        exit(1);    
      }
     
      // création de l'identifiant de la socket d'écoute du serveur
      bzero((char *) &addr_serveur, sizeof(addr_serveur));
      addr_serveur.sin_family = AF_INET;
      addr_serveur.sin_port = htons(4000);
      memcpy(&addr_serveur.sin_addr.s_addr, 
    	 host_serveur->h_addr, host_serveur->h_length);  
     
      // connexion de la socket client locale à la socket coté serveur
      if (connect(sock,(struct sockaddr *)&addr_serveur, sizeof(struct sockaddr_in)) == -1) {
        perror("erreur connexion serveur");
        exit(1);
      }
     
      // connexion etablie, on envoie le message
    	int nombre=4000;
      	nb_octets = write(sock, &nombre, sizeof(nombre));
     
     
      // on ferme la socket
      close(sock);
    }

  7. #7
    Invité(e)
    Invité(e)
    Par défaut
    Si read retourne -1, c'est qu'un problème est arrivé...

    Tu peux appeler la fonction perror pour savoir ce qui s'est passé.

    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
    void * fn_thread ( void * c )
    {
        int socket_service=(int)(c);
        printf("ici");
     
        int nb_octets;
        int nombre;
        nb_octets = read(socket_service, &nombre, sizeof(nombre));
     
        if(-1 == nb_octets) {
            /* Erreur de réception, on écrit la raison. */
            perror("read");
        }
     
        printf("%d",nombre);
     
        fflush(stdout);
        return NULL;
     
     
    }

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 11
    Par défaut
    c'est une erreur bad file descriptor.

  9. #9
    Invité(e)
    Invité(e)
    Par défaut
    As tu essayé d'utiliser recv plutôt que read ? (de même utiliser send plutôt que write)
    En effet, les read /write sur socket ne fonctionnent pas sur toutes les plateformes. En utilisant recv / send, on a moins de surprises.

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 11
    Par défaut
    je viens d'essayer avec recv et send mais le résultat est le même , perror affiche toujours un bad file descriptor. Avec un fork() ca marche sans probleme mais je dois utiliser les threads et ça commence à me désespérer .

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 11
    Par défaut
    Le problème est résolu. Il se trouvait ici

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    		  }
    	       int creation_thread=pthread_create(&thread[compteur],NULL,fn_thread,(void *)socket_service);
    									if(creation_thread!=0)
    									{
    									perror("pthread_create");
    									}
    			close(socket_service);				
    			compteur++;
    Il fallait enlever le close(socket_service) qui devait la rendre inutilisable dans fn_thread

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

Discussions similaires

  1. Serveur socket multi client qui bloque sur le premier client
    Par cyclopsnet dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 07/05/2014, 21h31
  2. Serveur TCP(perl) /Client TCP(cpp)
    Par Alex_Zesac dans le forum Programmation et administration système
    Réponses: 0
    Dernier message: 27/01/2012, 11h26
  3. Serveur multi-clients UDP TCP
    Par ludovskys dans le forum Réseau
    Réponses: 2
    Dernier message: 23/12/2011, 12h29
  4. [TCPServer/Client] Communication TCP multi-clients
    Par prgasp77 dans le forum Web & réseau
    Réponses: 1
    Dernier message: 14/12/2008, 16h04

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