Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
928 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] Un chat simple en C

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Un chat simple en C

n°690101
toutoune
Posté le 01-04-2004 à 19:00:27  profilanswer
 

Salut à tous!
J'ai besoin de faire un chat très simple en ligne de commande en C, avec un serveur et plusieurs clients.
Voilà en gros mon code (inspiré de CPPFrance):

Code :
  1. server=socket(AF_INET,SOCK_STREAM,0);
  2. bind(server,(SOCKADDR*)&sinserv,sizeof(sinserv));
  3. listen(server,0);
  4. char buffer[N];
  5. memset(buffer,0,sizeof(buffer));
  6. int sinsize;
  7. int err=0;
  8. while(1)
  9.     {
  10.      sinsize=sizeof(sin);
  11.     if((sock=accept(server,(SOCKADDR*)&sin,&sinsize))!=INVALID_SOCKET)
  12.         {
  13.               while(1)
  14.               { 
  15.                 recv(sock,buffer,sizeof(buffer),0);
  16.                 printf("%s\n",buffer);
  17.         }
  18.       }
  19.     }


Le problème, c'est que quand un nouveau client vient se connecter, le serveur est déjà dans sa boucle infinie en attendant de reçevoir des infos du premier client.
Comment je peux faire pour séparer les différents clients?
Je suis sous windows, je dois utiliser des threads?

mood
Publicité
Posté le 01-04-2004 à 19:00:27  profilanswer
 

n°690110
cricri_
Posté le 01-04-2004 à 19:21:15  profilanswer
 

Moi c'est ce que je fais effectivement, dès qu'il y a une connection j'ouvre un thread.
Sinon il faut utiliser select avec un time-out je pense, mais c'est moins pratique.

n°690112
toutoune
Posté le 01-04-2004 à 19:22:14  profilanswer
 

le problème avec un thread, c'est que je dois passer quoi en argument pour récupérer le socket qui a été ouvert?

n°690115
cricri_
Posté le 01-04-2004 à 19:23:08  profilanswer
 

passe un pointeur sur une structure avec les données dont tu as besoin.

n°690123
toutoune
Posté le 01-04-2004 à 19:26:32  profilanswer
 

je peux pas juste passer le sock en argument?

n°690129
cricri_
Posté le 01-04-2004 à 19:34:25  profilanswer
 

si bien sûr, si tu n'as besoin que de ça ;)

n°690139
toutoune
Posté le 01-04-2004 à 19:59:10  profilanswer
 

ok je vais essayer...

n°690161
Taz
bisounours-codeur
Posté le 01-04-2004 à 20:52:26  profilanswer
 

sizeof variable
sizeof(Type)

n°690347
toutoune
Posté le 01-04-2004 à 23:55:09  profilanswer
 

j'ai essayé de faire
pthread_create(&thread1, NULL, (void*)&thread_serveur, (void*) sock);
 
mais je crois que j'ai un pb du côté de mon (void*) sock...??
 

n°690362
Taz
bisounours-codeur
Posté le 02-04-2004 à 00:09:09  profilanswer
 

pourquoi tu cast ? si t'as besoin de caster, c'est que tu as un problème
 
int  pthread_create(pthread_t  *  thread,  pthread_attr_t * attr, void * (*start_routine)(void *),
       void * arg);

mood
Publicité
Posté le 02-04-2004 à 00:09:09  profilanswer
 

n°690985
toutoune
Posté le 02-04-2004 à 15:45:28  profilanswer
 

bon bon j'ai réussi avec les threads... mais maintenant, un autre pb!
Le serveur reçoit bien tout ce que les clients envoient, mais maintenant j'aimerais qu'il renvoi un message à tous les sockets connectés à lui même...
je pensais faire une boucle sur tous les sockets et faire un send à chaque fois, c'est la bonne méthode?

n°690998
cricri_
Posté le 02-04-2004 à 15:53:57  profilanswer
 

C'est plus simple de le faire par thread, et puis c'est le même code.

n°691111
toutoune
Posté le 02-04-2004 à 17:34:56  profilanswer
 

oui mais je voudrais envoyer le MEME message à tous... or les thread sont apparement indépendant? Comment faire communiquer des threads entre eux?

n°691212
cricri_
Posté le 02-04-2004 à 18:44:06  profilanswer
 

Il doit falloir utiliser les Events pour ça, mais je n'en sais pas plus ...

n°691340
toutoune
Posté le 02-04-2004 à 21:22:52  profilanswer
 

et tu crois pas qu'une boucle sur les sockets serait bien? le pb c'est que dans un thread je peux pas savoir quelles sont les connexions qui ont été ouvertes?
d'autres solutions?

n°691344
cricri_
Posté le 02-04-2004 à 21:36:28  profilanswer
 

Sinon tu peux envoyer un message dans la structure passé au thread, mais tu n'auras aucun compte rendu

n°691377
toutoune
Posté le 02-04-2004 à 22:13:33  profilanswer
 

hin?? comment ça?

n°691505
cricri_
Posté le 03-04-2004 à 09:12:09  profilanswer
 

Et bien au lieu de ne passer que la variable sock à ton thread, tu passes un pointeur sur une structure, et dedans tu y mets ta variable socket et une variable message.
Et dans ta boucle de chaque thread tu lis cette variable et s'il y a qqchose tu traites, puis tu remets à 0 par example pour indiquer que c'est pris en compte.
Il faut utiliser les critical section pour éviter de lire/écrire en même temps et ça doit rouler.

n°691657
toutoune
Posté le 03-04-2004 à 14:43:06  profilanswer
 

a ok... je vais voir ça! merci!

n°691875
toutoune
Posté le 03-04-2004 à 21:06:13  profilanswer
 

une question de newb'... comment on passe plusieurs arguments de types différents à un thread?

n°691876
cricri_
Posté le 03-04-2004 à 21:10:16  profilanswer
 

Passe un pointeur sur une structure !

n°691890
Taz
bisounours-codeur
Posté le 03-04-2004 à 21:27:08  profilanswer
 

Cricri_ a écrit :

Passe un pointeur sur une structure !
 

mais il est ou le poste ou j'ai collé une exemple complet ?

n°691898
cricri_
Posté le 03-04-2004 à 21:36:13  profilanswer
 

:pt1cable:  
Joker chef ..
je fais ce que je peux pour aider le monsieur, je n'ai pas d'autres prétentions ...
vi, l'est où le post ???  :ange:

n°691918
toutoune
Posté le 03-04-2004 à 21:49:07  profilanswer
 

oh ben oui il est ou l'exemple? :d
 
bon sinon, j'ai un problème pour passer une structure en argument :(
dans mon proto j'ai
 
void ouverture_serveur(struct arg_serveur);
 
et à la compil', devc++ me mets
 
[Warning] `struct arg_serveur' declared inside parameter list
[Warning] its scope is only this definition or declaration, which is probably not what you want
 
...

n°691932
Taz
bisounours-codeur
Posté le 03-04-2004 à 21:56:43  profilanswer
 
n°691947
toutoune
Posté le 03-04-2004 à 22:05:02  profilanswer
 

ok merci je vais étudier ça!

n°693076
toutoune
Posté le 06-04-2004 à 01:15:44  profilanswer
 

bon bon finalement après trop de galère, j'ai préféré faire une boucle sur mes sockets et ça roule!

n°693092
jagstang
Pa Capona ಠ_ಠ
Posté le 06-04-2004 à 01:53:11  profilanswer
 

quand c'est terminé, mets à dispo le code complet stp

n°693142
Deaddy
Posté le 06-04-2004 à 08:30:56  profilanswer
 

Citation :

Sinon il faut utiliser select avec un time-out je pense, mais c'est moins pratique.


 
c'est bien plus pratique à mon avis  :love:

n°693237
toutoune
Posté le 06-04-2004 à 10:09:44  profilanswer
 

ok je posterais ça dès que ça sera propre!

n°695504
toutoune
Posté le 08-04-2004 à 14:36:03  profilanswer
 

Voilà mon code...
Me reste encore un pb... quand un tous les clients sont déco... le serveur part dans une boucle infinie sur le dernier message!

Code :
  1. #include<stdlib.h> 
  2. #include<unistd.h> 
  3. #include<stdio.h> 
  4. #include<winsock2.h>
  5. #include<io.h>
  6. #include<pthread.h>
  7. #include<sys/types.h>
  8. #define N 1000
  9. #define MAX 5
  10. void serveur();
  11. void client();
  12. void ouverture_client(SOCKET sock);
  13. void ouverture_serveur(SOCKET sock);
  14. SOCKET socks[MAX];
  15. int nb_connecte;
  16. main()
  17. {
  18. int c;
  19. printf("Que souhaitez vous lancer?\n1. Serveur\n2. Client\n" );
  20. scanf("%d",&c);
  21. if(c==1) serveur();
  22. if(c==2) client();
  23. }
  24. // Prog Serveur **************************************************
  25. void serveur()
  26. {
  27.     WSADATA wsa;
  28.     WSAStartup(MAKEWORD(2,0),&wsa);
  29.    
  30.     SOCKET server;       
  31.     SOCKET sock;
  32.     SOCKADDR_IN sinserv;   
  33.     SOCKADDR_IN sin;       
  34.     int port;
  35.    
  36.     printf("Port : " );
  37.     scanf("%i",&port);
  38.     sinserv.sin_family=AF_INET;
  39.     sinserv.sin_addr.s_addr=INADDR_ANY;
  40.     sinserv.sin_port=htons(port);
  41.     server=socket(AF_INET,SOCK_STREAM,0);
  42.    
  43.     bind(server,(SOCKADDR*)&sinserv,sizeof(sinserv));
  44.    
  45.     listen(server,0);
  46.     char buffer[N];
  47.     int sinsize;
  48.     int err=0;
  49.     pthread_t thread_serveur;
  50.    
  51.     while(1)
  52.     {
  53.         sinsize=sizeof(sin);
  54.         if((sock=accept(server,(SOCKADDR*)&sin,&sinsize))!=INVALID_SOCKET)
  55.         {
  56.         socks[nb_connecte]=sock;
  57.         pthread_create(&thread_serveur,  NULL, (void*)&ouverture_serveur,sock);
  58.         nb_connecte++;
  59.        
  60.         }
  61.     }
  62. }
  63. void ouverture_serveur(SOCKET sock)
  64. {
  65. int b;
  66. printf("Client Connecté\n" );
  67. char buffer[1000];
  68. while(1)
  69.     {
  70.     if(recv(sock,buffer,sizeof(buffer),0))
  71.         {
  72.         printf("Message reçu d'un client, le serveur traite l'info et envoi une réponse à tous les autres\n" );
  73.         for(b=0;b<nb_connecte;b++)
  74.                 {
  75.                 send(socks[b],buffer,sizeof(buffer),0);
  76.                 }
  77.         }
  78.     }
  79. }
  80. // Prog Client **************************************************
  81. void client()
  82. {
  83.     WSADATA wsa;
  84.     WSAStartup(MAKEWORD(2,0),&wsa);
  85.     SOCKET sock;   
  86.     SOCKADDR_IN sin;
  87.     printf("Ip : " );
  88.     char ip[15];   
  89.     scanf("%s",ip);
  90.    
  91.     printf("%s","\nPort : " );
  92.     int port; 
  93.     scanf("%i",&port);
  94.    
  95.     sin.sin_family=AF_INET;
  96.     sin.sin_addr.s_addr=inet_addr(ip);
  97.    
  98.     sin.sin_port=htons(port);
  99.    
  100.     sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  101.     bind(sock,(SOCKADDR*)&sin,sizeof(sin));
  102.     if(connect(sock,(SOCKADDR*)&sin,sizeof(sin)))
  103.     {
  104.         printf("La connection a echoue\n" );
  105.         system("PAUSE" );
  106.         exit(0);
  107.     }
  108.     char buffer[N];
  109.     int err=0;
  110.    
  111.     pthread_t thread_client;
  112.     pthread_create(&thread_client,  NULL, (void*)&ouverture_client,sock);
  113.    
  114.     while(1)
  115.     {
  116.         gets(buffer);
  117.         send(sock,buffer,sizeof(buffer),0);
  118.        
  119.     }
  120.     printf("Connection terminée\n\n" );
  121.     WSACleanup();
  122.     system("PAUSE" );
  123. }
  124. void ouverture_client(SOCKET sock)
  125. {
  126.     char buffer[N];
  127. while(1)
  128.     {
  129.     if(recv(sock,buffer,sizeof(buffer),0))
  130.         {
  131.         printf("Serveur > %s\n",buffer);
  132.         }
  133.     }
  134. }

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] Un chat simple en C

 

Sujets relatifs
Taille de boutons simple et feuille de stylesécurité simple asp pour mot de passe
[JApplet] Interaction MySQL et applet /pb simple de resulset :ocomplexite algo, question simple
[PHP MYSQL] Question simple...Probleme simple , mais je trouve pas !
SWT - exemple simple[PHP/MYSQL]Ne peut on pas faire plus simple ?
[PYTHON/C API] Exemple simple?javascript: je m'embrouille dans un turc tout simple
Plus de sujets relatifs à : [C] Un chat simple en C


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR