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

  FORUM HardWare.fr
  Programmation
  C++

  [socket] select() ou fork()?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[socket] select() ou fork()?

n°1062228
mellie35
Posté le 27-04-2005 à 09:24:49  profilanswer
 

Bonjour!
 
Je développe un serveur communiquant par sockets TCP dont la contrainte principale est d'être portable sous linux et sous windows.
Ce serveur doit accepter plusieurs connexions (et réception de message) simultanées. Pour gérer cela, j'hésitais entre le classique fork et un select(). J'ai finalement implémenté ce serveur multi-clients avec un select() et les macros FD_SET, FD_ISSET...
Les connexions et les échanges de messages fonctionnent correctement en simultané, mais j'ai quand même un problème. Mon programme s'enmêle les pinceaux avec les IP des clients!! :??:  
 
J'ai créé une classe Masocket, ce qui permet d'éclaircir le code et de gérer la portabilité de manière transparente. Je déclare 1 objet Masocket correspondant au listener et un tableau contenant les objets Masocket correspondant au clients. Dans les exemples de code que j'ai pu trouver pour illuster l'utilisation du select(), les sockets sont toujours des int (unix).
Pour que ce soit plus clair, voici mon code :

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "Masocket.h"
  4. #ifdef _WIN32
  5. #include <winsock2.h>
  6. #pragma  comment(lib,"ws2_32.lib" )
  7. #else
  8. #include <unistd.h>
  9. #include <sys/socket.h>
  10. #include <sys/types.h>
  11. #include <netinet/in.h>
  12. #include <arpa/inet.h>
  13. typedef struct sockaddr_in SOCKADDR_IN;
  14. #endif
  15. #define PORT 3490
  16. #define MAXMSG 255
  17. Masocket clist [5];
  18. Masocket listener = Socketiam();
  19. fd_set master;
  20. fd_set temp;
  21. int fdmax;
  22. int i;
  23. void read_socks(){
  24. int listnum, client,newclient;
  25. bool loadsock=false;
  26. bool findsock=false;
  27. // run through the existing connections looking for data to read
  28.             for(i = 0; i <= fdmax; i++) {
  29.                 if (FD_ISSET(i,&temp)) {
  30.                     if (i == listener.getSock()) { //handle new connections
  31.   for (listnum = 0; listnum < 5 && (!loadsock); listnum++) {
  32.   if (clist[listnum].getSock()==0) {
  33.    newclient=listnum;
  34.    loadsock=true;
  35.   }
  36.  }
  37.  if (listener.acceptSock(clist[newclient])) {
  38. FD_SET(clist[newclient].getSock(),&master); // add to master set
  39. if (clist[newclient].getSock() > fdmax) {    // keep track of the maximum
  40. fdmax = clist[newclient].getSock();
  41. }
  42. printf("Got connection from \n",inet_ntoa(clist[newclient].getClientAddr().sin_addr));
  43. }
  44. }
  45. else { // handle data from a client
  46. for (listnum = 0; listnum < 5 && (!findsock); listnum++) {
  47. if (clist[listnum].getSock()==i) {
  48.      client=listnum;
  49.      findsock=true;
  50. }
  51. }
  52. if (clist[client].receive()==-1){
  53. printf(inet_ntoa(clist[client].getClientAddr().sin_addr));
  54. printf(" deconnect\r\n" );
  55. clist[client].kill(2);
  56. clist[client].closeSock();
  57. FD_CLR(i, &master); // remove from master set
  58. }
  59. }
  60. } // if
  61. } //for
  62. }
  63. void main(){
  64. int readsocks;      /* Number of sockets ready for reading */
  65. printf("Serveur demarre...\r\n" );
  66. listener.initSock(PORT,"" );
  67. listener.initServer(10);
  68. FD_ZERO(&master);
  69. FD_ZERO(&temp);
  70. listener.setinFD(master);
  71. fdmax = listener.getSock();
  72. while(TRUE)
  73. {
  74.  temp = master; // copy the master fd_set
  75.  readsocks =select(0, &temp, NULL, NULL, NULL);
  76.         if (readsocks < 0) {
  77.   perror("select" );
  78.   exit(EXIT_FAILURE);
  79.  }
  80.  if (readsocks == 0) {
  81.   printf("." );
  82.   fflush(stdout);
  83.  } else read_socks();
  84. }//while
  85. listener.closeSock();
  86. #ifdef _WIN32
  87. WSACleanup();
  88. #endif
  89. }


 
Concrètement, ma question est la suivante :  
Le fait que je manipule des objets non primitifs est-il un problème pour une gestion multi-clients avec select() ou ce problème peut-il être résolu? Est-ce fork() la solution pour conserver ma classe Masocket?
 
Question subsidiaire :  
Suis-je obligée de faire un tableau de Masocket? ou bien 1 Masocket pour le listener et 1 Masocket pour le client courant pourraient suffire?
Merci d'avance pour votre aide!

mood
Publicité
Posté le 27-04-2005 à 09:24:49  profilanswer
 

n°1071525
mellie35
Posté le 04-05-2005 à 11:52:14  profilanswer
 

J'ai finalement résolu mon problème toute seule, merci pour votre aide! Vraiment très concluant de poster sur ce forum!!
L'embrouille au niveau des adresses IP des clients n'était en fait qu'une illusion. Le serveur fonctionnait correctement. C'est l'appel à inet_noa() qui conserve la dernière adresse..
Sinon, j'ai changé la structure de stockage de mes sockets pour une map.

Code :
  1. #include <map>
  2. std::map <int,Masocket> clientsmap;


 
En espérant que ce sujet, aide quelqu'un à défaut de m'avoir aidé moi!
 


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

  [socket] select() ou fork()?

 

Sujets relatifs
Convertir requête Select en requête Update[JAVA] Transmettre une Socket...
[PB] Socket linux en Cpb avec onchange dans un select
[JS] options d'un selectformulaire avec select multiple
select() + multithreading[PHP] - Gérer les entrées dupliquées My SQL & Remplir un <SELECT>??
[Résolu] Comment obtenir le résultat -opposé- d'un SELECT ?[MySQL] Comment éviter une requete de type : Select ... Where .. IN .?
Plus de sujets relatifs à : [socket] select() ou fork()?


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