[C] Client/Serveur : tchat, envoi à tous les clients

Client/Serveur : tchat, envoi à tous les clients [C] - C - Programmation

Marsh Posté le 12-03-2007 à 19:33:22    

Bonjour,  
 
je suis entrain d'essayer de programmer un serveur qui accepte plusieurs clients, chaque clients peut parler, et alors les autres clients connectés doivent recevoir le message, cependant ca ne fonctionne pas vraiment mon code, et c'est plutot bizarre
 
 
Voici la partie du serveur qui fait default
 
A savoir que ca fonctionne, mais de manière etrange  :heink:  
je m'explique ... si j'ai trois clients qui se connecte, le derniere clients connecté qui envoit son message, le serveur le retransmet sur les deux autres,  
si le deuxième client envoit un msg, il sera retransmit uniquement sur le premier client, et si le premier client envoit un msg, personne le recevra..
 
Don en gros, pour l'instant mon code renvoit le message uniquement aux clients connectés avant le client qui ecrit le message...

Code :
  1. do{
  2. listen(sock,10);
  3. i++;
  4. sockt[i]= accept(sock, NULL, NULL);
  5. printf("Valeur de i : %i\n",i);
  6. fcntl(STDIN_FILENO,F_SETFL,fcntl(STDIN_FILENO,F_GETFL)|O_NONBLOCK);
  7. fcntl(sockt[i],F_SETFL,fcntl(sockt[i],F_GETFL)|O_NONBLOCK);
  8. write(sockt[i], msg, sizeof(msg));
  9. pid = fork();
  10. if(pid>0)
  11. {
  12. do{
  13.  memset(msg2,0,256); //remet à 0 la chaine de caractere
  14.  memset(msg_emis,0,256);
  15. //ECOUTE LE CLIENT
  16.  if(read(sockt[i],msg2,sizeof(msg2))>0)
  17.  {
  18.   printf("la phrase recue du client est : %s \n",msg2);
  19.   for(j=0;j<=10;j++)
  20.   {
  21.    if(j!=i)
  22.    {
  23.    write(sockt[j],msg2,sizeof(msg2));
  24.    }
  25.    else
  26.    {//Ne fait rien;
  27.    }
  28.   }
  29.   dif = strncmp(msg2,msg_fin,strlen(msg_fin));//compare pour la condition de fin
  30.  }
  31. }while(1);
  32. close(sockt[i]);
  33. }
  34. else
  35. {
  36. }
  37. }while(1);


 
Merci beaucoup d'avance si quelqu'un trouve la solution  :hello:

Reply

Marsh Posté le 12-03-2007 à 19:33:22   

Reply

Marsh Posté le 12-03-2007 à 19:52:21    

Je pense que fork copie la mémoire mais que les processus ne la partage pas, donc à chaque fois que tu rajoutes un client, il connait ceux d'avant mais les autres ne le connaissent pas puisque la socket est "ajoutée" dans la mémoire du fils.
Peut être que si tu fais le read() dans le processus fils au lieu du père, le fils aura accès au "bon tableau de sockets" mais je n'en suis pas sûr. Sinon utilise des threads...
Donne la solution quand tu l'auras trouvée stp, ça m'intéresse.


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 13-03-2007 à 14:13:36    

select() est beaucoup plus adapte pour ca.
http://beej.us/guide/bgnet/output/ [...] tml#select
 
en gros chaque fois que tu accepte un client (avec accept()) tu ajoute cette nouvelle socket dans une sorte de "liste" de file descriptors a surveiller (tu surveilles si ya des nouvelles donnees a lire, ou a ecrire, dessus.) Puis tu appelles select avec comme parametre cette liste, et un eventuel laps de temps pendant lequel select va bloquer en attendant des donnees. Quand tu sors de select avant la fin du laps de temps, tu parcours la liste de tes fd (avec for par exemple) et tu verifie si c'est un file descriptor ayant des donnees en attente (avec FD_ISSET), et si c'est le cas, par exemple en lecture, bah tu lis dessus, et dans le cas d'un serveur de tchat par exemple, tu re-parcours tous les files descriptors en ecrivant dessus ce que tu viens de lire sur le filedescriptor ayant des donnees.
 
Voila, c'est tres grossierement resume, mais l'idee y est.


Message édité par meik le 13-03-2007 à 14:17:41
Reply

Marsh Posté le 13-03-2007 à 16:55:30    

exact.
C'est comme ça que j'avais fait à l'IUT.
C'est coté client que j'avais fait un thread avec un read pour afficher les messages reçus même pendant que l'utilisateur tapais un message (en utilisant bêtement scanf).


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 13-03-2007 à 17:28:36    

je vais essayer, je vous tiens au courant

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed