Partage
  • Partager sur Facebook
  • Partager sur Twitter

socket serveur thread pour plusieurs client

Anonyme
    27 décembre 2015 à 19:05:49

    Salut, j'essaye de faire un socket serveur avec des thread pour plusieurs client 

    Le truc c'est que je n'arrive pas a avoir plusieurs client sur mon serveur.

    Voila le code du serveur : 

    int main()
    {
    
    
    /* Déclaration des variables */
    int sockserveur,newsockfd,lg, *new_sock;
    struct sockaddr_in coord_client;
    struct sockaddr_in mes_coord;
    struct tm *m;
    /* Création d'un socket */
    sockserveur=socket(AF_INET, SOCK_STREAM, 0);
    /* Serveur : appel BIND */
    /* Serveur : appel LISTEN */
    /* Serveur : appel ACCEPT */
    	lg=sizeof(coord_client);
    	while(newsockfd=accept(sockserveur,(struct sockaddr*)&coord_client,&lg)){
    // ici quand in client se connect on creer un thread
    	pthread_t th;
       new_sock = malloc(sizeof(new_sock));
       *new_sock = newsockfd;
    
       (pthread_create(&th, NULL,  connection,  (void *) new_sock);
    
       pthread_join(th, NULL);
    	
    	close(newsockfd);
    	}
    close(sockserveur);
    }
    
    void *connection(void *socket){
        int sock = *(int*)socket;
    
     //traitment
     
    	while(1){
    //ensemble d'instructions avec read et write
    	}
    	
        close(sock);
    }

    Donc en faite, quand je n'ai rien dans le while(1) dans la fonction, plusieurs client peuvent se connecter, mais du moment ou j'ai un read dans ma fonction, le serveur est comme bloqué sur un client et je ne peux plus connecter d'autres client.

    -
    Edité par Anonyme 27 décembre 2015 à 19:06:10

    • Partager sur Facebook
    • Partager sur Twitter
      27 décembre 2015 à 23:17:58

      pthread_join bloque ta boucle car elle attend que le 1er thread finisse !  Ca revient à faire du mono-thread.
      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        27 décembre 2015 à 23:41:01

        ah oui merci ça marche si je l'enleve.

        Du coup, je doit le mettre a la fin de mon main, et je doit déclarer mon thread avant l'appel a accept, donc juste au dessus de la boucle while ? 

        • Partager sur Facebook
        • Partager sur Twitter
          28 décembre 2015 à 0:54:56

          T'as pas besoin de faire un pthread_join puisqu'une fois le thread terminé t'as plus besoin de la session.

           (si le sujet est résolu, mets le en résolu et un petit plus me ferait du bien :-D  )



          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            28 décembre 2015 à 1:37:49

            bah si, il faut toujours mettre le pthread_join, juste pour etre sûr

            C'est pour que le programme principale ne se termine pas tant que les threads sont en cours il me semble.

            -
            Edité par Anonyme 28 décembre 2015 à 1:39:47

            • Partager sur Facebook
            • Partager sur Twitter
              28 décembre 2015 à 10:20:46

              dans ce cas tu fais un pthread_exit dans les threads quand ils sont terminés, ou bien tu fais une des choses suivantes : 

              solution 1.avant de lancer la boucle du serveur :
              - tu lances un thread de controle qui se chargera d'arrêter tous les threads clients (pthread_cancel() ) quand le serveur s'arrête. Cela implique que les threads doivent être stockés dans un tableau ou une structure équivalente.

              solution 2.chaque fois qu'un client se connecte, tu stockes son thread dans un tableau dynamique (vector, list en c++ OU liste chainée en C ou autre).
              Quand le serveur doit s'arrêter, tu fais un pthread_cancel() sur tous les thread en cours. 

              Pour bien annuler un thread, il faut donc rendre ces threads annulables. Dans la fonction callback du thread, il faut appeler : 

              int pthread_setcancelstate(int state, int *oldstate);

               avec state à PTHREAD_CANCEL_ASYNCHRONOUS et oldstate à  NULL

              -
              Edité par blixit 28 décembre 2015 à 10:39:51

              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                28 décembre 2015 à 19:12:45

                c'est compliqu ton truc la.

                Moi dans le thread je voulais mettre un pthread_exit a un moment, et dans le main un pthread_join avant de fermer le socket client sinon il le ferme alors que mon thread n'est pas terminé

                • Partager sur Facebook
                • Partager sur Twitter
                  28 décembre 2015 à 23:22:50

                  lol oublie ma solution si elle te semble compliquée. le but c'est pas de t'embrouiller.

                  Mais t'as pas compris un truc. Pthread_join ne sert pas à fermer un thread. Il permet d'attendre que le thread finisse de s'exécuter.
                  C'est utile dans le cas ou t'as 2 ou plusieurs threads concurrents dont tu attends le résultat.
                  Ex:
                  J'ai un vecteur de taille 10.000.000  dont je veux calculer la somme efficacement.
                  Je lance 4 threads (4 c'est arbitraire). donc chacun calcule la somme de 2.500.000 termes.
                  A la sortie, je veux la somme des 4 résultats donc à ce moment je DOIS faire un join puisque j'attends les résultats dont j'ai besoin pour calculer la somme totale.

                  Mais dans le cas du serveur, t'as pas besoin de faire parce qu'un thread s'exécute comme la fonction main() : un thread est un processus à part, quand il termine son exécution, il meurt!!  

                  -
                  Edité par blixit 28 décembre 2015 à 23:57:01

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    29 décembre 2015 à 0:52:10

                    oui justement c'est ça que je veux faire, je veux attendre que le thread finisse avant de fermer la socket, du coup j'utilise bien un pthread_join avant de faire un close sur la socket.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      29 décembre 2015 à 10:12:09

                      en vérité, je ne comprends pas l'obsession que t'as pour join, puisque t'en as pas besoin pour fermer la socket!!
                      la fonction callback client peut le faire. et c'est d'ailleurs ce qu'elle fait. au final, dans ton code actuel, tu fermes la socket 2 FOIS.
                      - dans la boucle du main : close(newsockfd);
                      - dans la fonction : close(sock);

                      je pense que ce que tu veux faire à tout prix (mais que tu ne fais pas au final), c'est libérer le pointeur initialisé avec malloc : donc faire un free(). 
                      Mais là encore pas la peine, il suffit de passer l'adresse de la variable a la fonction. Si tu veux a tout prix utiliser malloc, la fonction peut se charger de faire le free().

                      Si une chose est certaine, c'est que l'utilisation de join ne te permettra pas de faire un serveur multitache dans ton cas.
                      voici, une option qui, je le pense,  devrait fonctionner.

                      int main()
                      {
                      
                          while(1){
                      /* Déclaration des variables */
                      int sockserveur,newsockfd,lg, *new_sock;
                      struct sockaddr_in coord_client;
                      struct sockaddr_in mes_coord;
                      struct tm *m;
                      /* Création d'un socket */
                         sockserveur=socket(AF_INET, SOCK_STREAM, 0);
                         if(sockserveur==-1)
                             break; //en cas d'erreur on arrete
                      /* Serveur : appel BIND */
                      /* Serveur : appel LISTEN */
                      /* Serveur : appel ACCEPT */
                          lg=sizeof(coord_client);
                      
                          newsockfd=accept(sockserveur,(struct sockaddr*)&coord_client,&lg);
                          if(newsockfd==-1)
                              break; //en cas d'erreur on arrete
                      
                      // ici quand in client se connect on creer un thread
                          pthread_t th;  
                       
                         pthread_create(&th, NULL,  connection,  (void *) (&newsockfd)); 
                      //PAS DE JOIN, le thread client vie sa vie ...
                      //on ferme sockserveur et on recommence     close(sockserveur);         } }   void *connection(void *socket){     int sock = *(int*)socket;    //traitment        while(1){ //ensemble d'instructions avec read et write     }           close(sock); }

                      -
                      Edité par blixit 29 décembre 2015 à 11:34:50

                      • Partager sur Facebook
                      • Partager sur Twitter
                        29 décembre 2015 à 11:35:34

                        En fin de compte, c'est toi qui décide de ce que tu codes. Tout ce que je dis, vois ça comme des suggestions.
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          29 décembre 2015 à 17:05:09

                          Mais en faite en cours j'ai toujours vu qu'il fallait mettre en a la fin quand on creer des threads pour ne pas terminer le programme principal tant que les threads ne sont pas fini.

                          Par contre j'ai pas compris pourquoi tu as enlever la boucle du accept, parce que la du coup tu lance le thread et ferme le socket serveur du coup, mon programme serveur s'arrete.

                          Donc mon code comme il est au dessus il est bon faut juste que l'enleve le join et close(newsockfd).

                          Par conter quand j'éteins le client avec ctrl+c, du coté serveur, je sors de ma boucle while du accept et du coup je passe par close(sockserveur) et du coup mon serveur s'éteint en meme temps.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            19 juin 2019 à 6:45:08

                            On considère une application client-serveur.
                            Cette application permet de réserver des places pour un ensemble de spectacles.
                            Des processus clients remettent deux types de requêtes à destination du serveur de 
                            réservation :
                            - requête de consultation permettant de consulter le nombre de places restantes pour 
                            un spectacle donné.
                            - requête de réservation permettant de réserver n places pour un spectacle donné. 
                            Le serveur de réservation est composé de deux processus :
                            - un processus serveur Consultation prend en compte les requêtes de consultation. 
                            Pour chacune d’elle, il renvoie le nombre de places disponibles pour le spectacle
                            spécifié dans la requête.
                            - un processus serveur Réservation prend en compte les requêtes de réservation. 
                            Pour chacune d’elle, il créé un processus fils qui effectue la réservation si cela est 
                            possible. Dans le cas où la réservation a pu être faite, le processus fils renvoie au 
                            client un acquittement de réservation et sinon un message d’erreur.
                            Les informations concernant les spectacles sont stockées dans une table en mémoire centrale. 
                            Une entrée de la table concerne un spectacle et donne les informations suivantes : Intitulé du 
                            spectacle, nombre de places restantes. Chaque spectacle est joué une seule fois.
                            Travail demandé
                            1/ Processus lourds 
                            On implémente cette application avec des processus lourds. Clients etserveurs sont sur une 
                            même machine.
                            o Choisissez les outils de communication qui vous paraissent les plus adaptés entre d’une 
                            part, les clients et les serveurs, d’autre part entre le processus Réservation et ses fils. 
                            Justifiez votre choix.
                            o Détaillez la structure des messages échangés entre les processus .
                            o Spécifiez une solution permettant de réaliser les actions décrites dans l’énoncé. Vous 
                            donnerez notamment les codes de chacun des processus suivants :
                            o le processus Client ;
                            o le processus Réservation
                            o le processus fils du processus Réservation
                            o le processus Consultation
                            Si possible vous utilisez au moins une fois une primitive de recouvrement.
                            2/ Processus légers 
                            Les serveurs Consultation et Réservation sont maintenant construits comme un seul processus 
                            avec différents fils d’exécution. Donnez le pseudo code de ce serveur.
                            3/Bonus 
                            Les serveurs Consultation et Réservation sont sur des machines différentes. Modifiez les 
                            pseudo codes en conséquence.
                            Votre document rendu comporte :
                            o Vos noms et prénoms ;
                            o Quelques pages justifiant vos choix (outils de communication, structure des messages 
                            échangés, algorithmes des processus) ;
                            o Les pseudo codes commentés des processus.
                            o Si possible au moins un processus implémenté en C.
                            • Partager sur Facebook
                            • Partager sur Twitter
                            • koudoussou.ouattara.96

                            socket serveur thread pour plusieurs client

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            • Editeur
                            • Markdown