[Langage C] Problème d'affichage Chat 2 clients

Problème d'affichage Chat 2 clients [Langage C] - C - Programmation

Marsh Posté le 22-12-2017 à 13:28:36    

Bonjour,
 
Pour un projet scolaire, je dois développer un chat, avec 2 clients et 1 serveur.
J'arrive à connecter les 2 clients au serveur, à communiquer aucun soucis.
Mon problème survient lorsque je veux déconnecter 1 client, j'ai fait en sorte que si 1 client écrit le mot "disconnect", la connexion se coupe.
 
Seulement, au moment ou la connexion se coupe, la fenêtre du terminal est flood et je n'arrive pas à comprendre d'ou vient le problème.
 
J'ai un truc du genre sur le terminal :
 
Vous : disconnect
Vous :  
Serveur : Extinction du serveur...
Fermeture du processus...Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : client-eduroam779:Programmation sous UNIX shin$ Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : Vous : V
 
Idem sur l'autre client et au niveau du serveur :
Disconnect detected!
......... Indéfiniment
 
J'vous file le code :
 
Client :

Code :
  1. /*
  2. PROGRAMME CLIENT
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <arpa/inet.h>
  9. #include <netdb.h>
  10. #include <netinet/in.h>
  11. #include <sys/types.h>
  12. #include <sys/socket.h>
  13. #define BUFFER_SIZE 256
  14. // LISTE DES PROTOTYPES DES FONCTIONS //
  15. int cree_socket_tcp_ip(char* ip_socket, int port_socket);
  16. int affiche_adresse_socket(int sock);
  17. // FIN DE LA LISTE DES PROTOTYPES DES FONCTIONS //
  18. int cree_socket_tcp_ip(char* ip_socket, int port_socket)
  19. {
  20. int sock;
  21. struct sockaddr_in adresse;
  22. sock = socket(AF_INET, SOCK_STREAM, 0);
  23. // On gère les cas d'erreur
  24. if (sock < 0)
  25. {
  26.  fprintf(stderr, "Erreur socket\n" );
  27.  return -1;
  28. }
  29. memset(&adresse, 0,sizeof(struct sockaddr_in));
  30. adresse.sin_family = AF_INET;
  31. adresse.sin_port = htons(port_socket);
  32. inet_aton(ip_socket, &adresse.sin_addr);
  33. if(connect(sock, (struct sockaddr*) &adresse, sizeof(struct sockaddr_in)) < 0)
  34. {
  35.  close(sock);
  36.  fprintf(stderr, "Erreur connexion\n" );
  37.  return -1;
  38. }
  39. //printf("%u\n", ntohs(adresse.sin_port));
  40. //affiche_adresse_socket(sock);
  41. return sock;
  42. }
  43. int affiche_adresse_socket(int sock)
  44. {
  45. struct sockaddr_in adr;
  46. socklen_t longueur = sizeof(struct sockaddr_in);
  47. if((getpeername(sock, (struct sockaddr*)&adr, &longueur)) < 0)
  48. {
  49.  fprintf(stderr,"Erreur getsockname in Client.c, affiche_adresse_socket function\n" );
  50.  return -1;
  51. }
  52. printf("IP = %s, Port = %u\n", inet_ntoa(adr.sin_addr), ntohs(adr.sin_port));
  53. return 0;
  54. }
  55. int main(int argc, char* argv[]){
  56. // On contrôle si l'utilisateur a rentré le bon nombre d'arguments
  57. if(argc != 3)
  58. {
  59.  fprintf(stderr, "Mauvaise utilisation\n./client ip_adr port\n" );
  60.  exit(-1);
  61. }
  62. int sock;
  63. char bufferR[BUFFER_SIZE];
  64. char bufferW[BUFFER_SIZE];
  65. int nb;
  66. pid_t pid;
  67. // On crée le socket
  68. sock = cree_socket_tcp_ip(argv[1], atoi(argv[2]));
  69. if(sock < 0)
  70. {
  71.  fprintf(stderr, "Erreur creation socket (Main)\n" );
  72.  exit(-1);
  73. }
  74. nb = 3;
  75. //printf("Connexion reussie à l'adresse : " );
  76. pid = fork();
  77. if(pid == -1)
  78. {
  79.  fprintf(stderr,"Client : Fork error!\n" );
  80.  return -1;
  81. }
  82. else if(pid == 0)
  83. {
  84.  while(1)
  85.  {
  86.   printf("Vous : " );
  87.   fgets(bufferW, BUFFER_SIZE, stdin);
  88.   write(sock, bufferW, BUFFER_SIZE);
  89.  }
  90. }
  91. else
  92. {
  93.  while(nb > 0)
  94.  {
  95.   nb = read(sock, bufferR, BUFFER_SIZE);
  96.   if(strncmp(bufferR, "Extinction du serveur...", 24) == 0){
  97.    printf("\nServeur : %s", bufferR);
  98.    printf("\nFermeture du processus..." );
  99.    fflush(stdin);
  100.    fflush(stdout);
  101.    kill(pid);
  102.    sleep(2);
  103.    exit(1);
  104.   }
  105.   else{
  106.    bufferR[nb - 2] = '\0';
  107.    printf("\nUser : %s", bufferR);
  108.   }
  109.  }
  110. }
  111. close(sock);
  112. }


 
Serveur :
 

Code :
  1. /*
  2. PROGRAMME SERVEUR avec N-CLIENTS
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <arpa/inet.h>
  9. #include <netdb.h>
  10. #include <netinet/in.h>
  11. #include <sys/types.h>
  12. #include <sys/socket.h>
  13. #include <sys/shm.h>
  14. #include <errno.h>
  15. #include <string.h>
  16. #define BUFFER_SIZE 256
  17. #define NB_CLIENTS 2
  18. // LISTE DES PROTOTYPES DES FONCTIONS
  19. int cree_socket_tcp_ip(char* ip_socket, int port_socket);
  20. int affiche_adresse_socket(int sock);
  21. void traite_connection(int *list_client);
  22. void affiche_client(int *list_client);
  23. void affiche_ip_client(int client_sock);
  24. // FIN
  25. int cree_socket_tcp_ip(char* ip_addr, int port)
  26. {
  27. int sock;
  28. struct sockaddr_in serv_addr;
  29. //On gère les cas d'erreur
  30. sock = socket(PF_INET, SOCK_STREAM, 0);
  31. if(sock < 0)
  32. {
  33.  fprintf(stderr, "Erreur socket (cree_socket_tcp_ip function)\n" );
  34.  return -1;
  35. }
  36. memset(&serv_addr, 0, sizeof(struct sockaddr_in));
  37. serv_addr.sin_family = PF_INET;
  38. serv_addr.sin_addr.s_addr = INADDR_ANY;
  39. serv_addr.sin_port = htons(port);
  40. //On vérifie si le bind c'est bien passé
  41. if(bind(sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
  42. {
  43.  close(sock);
  44.  fprintf(stderr, "Erreur bind (cree_socket_tcp_ip function)\n" );
  45.  return -1;
  46. }
  47. return sock;
  48. }
  49. int affiche_adresse_socket(int descripteur_sock){
  50.         struct sockaddr_in adresse;
  51.         socklen_t longueur = sizeof(struct sockaddr_in);
  52. if (getpeername(descripteur_sock, (struct sockaddr*) &adresse, &longueur) < 0) {
  53.       fprintf(stderr, "Erreur getpeername" );
  54.       return -1;
  55. }
  56. printf("IP client : %s : %d\n", inet_ntoa(adresse.sin_addr), ntohs(adresse.sin_port));
  57.     return 0;
  58. }
  59. void traite_connection(int *list_client)
  60. {
  61. struct sockaddr_in adresse;
  62. socklen_t lg;
  63. char bufferR[BUFFER_SIZE];
  64. char bufferW[BUFFER_SIZE];
  65. int nb = 3;
  66. pid_t pid;
  67. lg = sizeof(struct sockaddr_in);
  68. int i;
  69. int j;
  70.     affiche_client(list_client);
  71. for(i = 0; i < NB_CLIENTS; i++){
  72.  if(getpeername(list_client[i], (struct sockaddr*)&adresse, &lg) < 0)
  73.  {
  74.   fprintf(stderr,"Erreur getpeername, Socket : %d", list_client[i]);
  75.   return;
  76.  }
  77. }
  78. // On crée autant de fils qu'il y a de clients sur le serveur
  79. for( i = 0; i < NB_CLIENTS; i++)
  80. {
  81.  pid = fork();
  82.  if(pid == -1)
  83.  {
  84.   fprintf(stderr, "Erreur fork lors du traitement de la connexion!\n" );
  85.   return;
  86.  }
  87.  else if(pid == 0) // Child processus
  88.  {
  89.   while(nb > 0)
  90.   {
  91.    nb = read(list_client[i], bufferR, BUFFER_SIZE);
  92.    if(strncmp(bufferR, "disconnect", 10) == 0){
  93.     printf("Disconnect detected!\n" );
  94.     strcpy(bufferW, "Extinction du serveur..." );
  95.     fflush(stdin);
  96.     fflush(stdout);
  97.     //affiche_client(list_client);
  98.     for(j = 0; j < NB_CLIENTS; j++){
  99.      //printf("Ecriture du message d'extinction...\n" );
  100.      write(list_client[j], bufferW, BUFFER_SIZE);
  101.     }
  102.     kill(pid);
  103.    }
  104.    else{
  105.     affiche_ip_client(list_client[i]);
  106.     printf(" : %s", bufferR);
  107.     bufferR[nb - 2] = '\0';
  108.     strcpy(bufferW, bufferR);
  109.     for(j = 0; j < NB_CLIENTS; j++)
  110.     {
  111.      if(j != i)
  112.       write(list_client[j], bufferW, BUFFER_SIZE);
  113.     }
  114.    }
  115.   }
  116.  }
  117.  fflush(stdout);
  118. }
  119. /*for(i = 0; i < NB_CLIENTS; i++)
  120.  wait();*/
  121. }
  122. void affiche_client(int *list_client)
  123. {
  124. int i;
  125. printf("List of client's socket :\n" );
  126. for (i = 0; i < NB_CLIENTS; i++)
  127.  printf(" %d ", list_client[i]);
  128. printf("\n" );
  129. }
  130. void affiche_ip_client(int client_sock)
  131. {
  132. struct sockaddr_in adresse;
  133.     socklen_t longueur = sizeof(struct sockaddr_in);
  134. if (getpeername(client_sock, (struct sockaddr*) &adresse, &longueur) < 0) {
  135.       fprintf(stderr, "Erreur getpeername" );
  136.       return;
  137. }
  138. printf("%s", inet_ntoa(adresse.sin_addr));
  139. }
  140. int main(int argc, char* argv[])
  141. {
  142. if(argc != 3)
  143. {
  144.  fprintf(stderr, "Mauvaise utilisation\n./client ip_adr port\n" );
  145.  exit(-1);
  146. }
  147. int sock_contact;
  148. int list_client[NB_CLIENTS];
  149. struct sockaddr_in client_addr;
  150. socklen_t client_lg = sizeof(client_addr);
  151. pid_t pid;
  152. sock_contact = cree_socket_tcp_ip(argv[1], atoi(argv[2]));
  153. if(sock_contact < 0)
  154. {
  155.  fprintf(stderr, "Erreur création socket_contact (Main function)\n" );
  156.  exit(-1);
  157. }
  158. //printf("Socket cree : %d\n", sock_contact);
  159. if(listen(sock_contact, 5) == -1)
  160. {
  161.  fprintf(stderr, "Server: listen failed!\n" );
  162.  return -1;
  163. }
  164. printf("Adresse du serveur : %s : %u\n", argv[1], atoi(argv[2]));
  165. printf("Waiting for connections...\n" );
  166. while(1)
  167. {
  168.  int i;
  169.  for(i = 0; i < NB_CLIENTS; i++)
  170.  {
  171.   list_client[i] = accept(sock_contact, (struct sockaddr *)&client_addr, &client_lg);
  172.   if(list_client[i] < 0)
  173.   {
  174.    fprintf(stderr,"Acceptation failed! for %d\n", i);
  175.    return -1;
  176.   }
  177.   affiche_adresse_socket(list_client[i]);
  178.  }
  179.  pid = fork();
  180.  if(pid == -1)
  181.  {
  182.   fprintf(stderr, "Erreur fork!\n" );
  183.   return -1;
  184.  }
  185.  if(pid == 0) // FIls se charge de traiter la communication entre les clients
  186.  {
  187.   int j = 0;
  188.   close(sock_contact);
  189.   //affiche_client(list_client);
  190.   traite_connection(list_client);
  191.   for(j= 0; j < NB_CLIENTS; j++)
  192.    close(list_client[j]);
  193.   exit(0);
  194.  }
  195.  else // Père close les sockets
  196.  {
  197.   int j = 0;
  198.   for(j = 0; j < NB_CLIENTS; j++)
  199.    close(list_client[j]);
  200.  }
  201. }
  202. return 0;
  203. }


 
Merci beaucoup! :)

Reply

Marsh Posté le 22-12-2017 à 13:28:36   

Reply

Marsh Posté le 22-12-2017 à 15:11:00    

Lignes 107 à 111 du programme client je dirais. Comment tu sors du while(1) ?


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 23-12-2017 à 17:55:32    

Yep en effet, c'était bien ça!
 
Merci beaucoup

Reply

Sujets relatifs:

Leave a Replay

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