Aide creation serveur t'chat

Signaler
Messages postés
11
Date d'inscription
mardi 2 décembre 2003
Statut
Membre
Dernière intervention
27 janvier 2010
-
Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
-
Bonjour

Je dois réaliser un projet qui consiste a faire un serveur de t'chat en c sous Linux.
je précise que je débute sous Linux et c également.

Mais voila après avoir bosser longuement dessus il ne fonctionne toujours pas.

c'est pour cela que je vous demain votre aide.
je sais également qu'il existe de nombreuses sources sur le site mais l'idée n'est pas de pomper le code d'un autre. et de comprendre ce que je fais et ou sont mais erreur.

voici ou j'en suis.

   #include <stdio.h>
   #include <fcntl.h>
   #include <sys/types.h>
   #include <sys/socket.h>
   #include <netinet/in.h>
   #include <stdlib.h>
   #include <netdb.h>
   #include 
   #include <string.h>
   #include<stdlib.h>
   #include
   #include<stdio.h>
   #include
   #include<sys/types.h>
   #define PORTS 1981

  void serveur(int sock);

  typedef struct	struc_client {int num_sck;
  					  char ip;
 					  }  s_client;
 s_client *clients[100];//tableau contenant les clients
 s_client *client;//un client
   int sock, nsock,i;
   int nb_client;

   main()
   {
       int sock, nsock;

       struct sockaddr_in adr_s, adr_c;
       typedef struct sockaddr SOCKADDR;
       client = (s_client *) malloc(sizeof(s_client));
       socklen_t lg_adr_c = sizeof(adr_c);
       sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
       if(sock != -1) {printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);}
       bzero(&adr_s,sizeof(adr_s));
       adr_s.sin_family=AF_INET;
       adr_s.sin_port= htons(PORTS);
       adr_s.sin_addr.s_addr = htonl(INADDR_ANY);
       if (bind(sock,(SOCKADDR *)&adr_s,sizeof(adr_s))!=-1){
            printf("construction adresse ok \n");
       }
       if(listen(sock,5)!=-1){
            printf("Patientez pendant qu'un client se connecte sur le port %d...\n", PORTS);
       }
       pthread_t thread_serveur;

       while(1)
       {
           nsock = accept(sock,(SOCKADDR *)&adr_c,&lg_adr_c);

           if(nsock!=-1){
                printf("un nouveau client vient de se connecter : %s \n",inet_ntoa(adr_c.sin_addr));
                client->num_sck = nsock;
                client->ip = inet_ntoa(adr_c.sin_addr);
                clients[nb_client] = client;
                printf("socket = %d\n",client->num_sck);

                pthread_create(&thread_serveur,  NULL, (void*)&serveur,client->num_sck);
                nb_client++;
                printf("il y a maintenant %i client sur le serveur.\n",nb_client);
                for(i=0;i<=nb_client-1;i++){
 				printf("et il existe la sockets : %d\n",clients[i]->num_sck);
 		}
           }
       }
   }

   void serveur(int sock){
   char buf[500];
   printf("entrer dans thread \n");
   while(1){

        if (read(sock,buf,500)!=-1){
 				printf("read\n");
 			};
 			for(i=0;i<=nb_client-1;i++){
 				write(clients[i]->num_sck,&buf,500);
 				printf("message envoyer sur le socket : %d\n",clients[i]->num_sck);
 			}

       }
   }



j'ai l'impression que mon problème vient de la structure en effet lorsque j'affiche
for(i=0;i<=nb_client-1;i++){
printf("et il existe la sockets : %d\n",clients[i]->num_sck);
}

tout les num_sock de la structure contient la valeur de la derrière socket créée.

je vous remerci d'avance de l'aide que vous pourriez m'apporter

2 réponses

Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
1
Salut,

Regarder un code existant n'est pas pomper. Si tu analyse le code, et essaie de faire pareil en changeant au fur et à mesure quelques trucs, c'est (selon moi) la meilleure façon d'apprendre.

Je ne vois pas de grosse erreur dans l'algo du code.
Par contre, client et clients[] sont 2 pointeurs (et tableau de pointeurs).
Quand tu fais "clients[nb_client] = client;", l'adresse de "client" est stockée dans la case du tableau. Or l'adresse de "client" ne change pas au cours du programme... donc toutes les cases pointeront sur cette même adresse (et récupèreront les mêmes valeurs des membres).

Soit tu supprimes les pointeurs, soit tu ajoutes une fonction qui alloue de la place mémoire, copie les valeurs des membres et la retourne. Du genre :
s_client *clientdup(s_client *c) {
    s_client *b=(s_client*)malloc(sizeof(s_client));
    b->num_sck=c->num_sck;
    b->ip=c->ip;
    return b;
}

clients[nb_client] = clientdup(client);

De cette manière, chaque case du tableau pointera sur une zone mémoire différente.

Il ne faudra pas oublier les free.
A vérifier, quand même


Cordialement, uaip.
Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
1
Ah oui, au passage :
i<=nb_client-1 devient i<nb_client (plus court, plus lisible)


Cordialement, uaip.