[C] Serveur multi-client avec pthread

Serveur multi-client avec pthread [C] - C - Programmation

Marsh Posté le 03-01-2006 à 10:47:42    

Bonjour à tous!
 
Au boulot, on vient de me filer le code d'un serveur et je dois le modifier. En gros, le serveur recoit des requetes contenant un nom d'utilisateur et une adresse ip. Chaque connexion est traitée par un processus (créé par un fork). Moi je dois modifier ce code pour stocker dans une table de hachage les couples (ip,login). J'ai déjà écrit le code pour la table de hachage mais le problème est de pouvoir la partager entre les différents processus. Chaque processus possède sa propre version de la table de hachage et donc je stocke rien en fait :(
 
J'ai des vagues souvenirs de mes cours de programmation système à la fac mais là ca m'aide pas beaucoup. Je pense  pas devoir utiliser la mémoire partagée... Peut être des tubes pour communiquer avec le processus père et que ce soit le processus père qui gère la table de hachage...
 
Si vous pouviez m'aiguiller un peu sur la méthode qui serait la plus appropriée dans mon cas, je vous remercie d'avance! :-)


Message édité par _p1c0_ le 05-01-2006 à 09:12:44
Reply

Marsh Posté le 03-01-2006 à 10:47:42   

Reply

Marsh Posté le 03-01-2006 à 12:40:46    

salut
moi j'y suis encore à la fac lol et je crois que tu ne peut passer soit par la communication (tubes, etc...), soit par la mémoire partagée; mais je sais pas ce qui est le mieux pour toi
 
du coup, la solution m'interesse aussi, tu devrais demander directement sur la mailing list apache - a mon avis y'a les spécialistes qu'il te faut la bas :)


Message édité par mehdi69 le 03-01-2006 à 12:41:17
Reply

Marsh Posté le 03-01-2006 à 14:12:05    

Dans un élan d'enthousiasme, au début, j'avais codé l'ajout dans la table de hachage dans la fonction de traitement de la connexion. Seul problème, ma table de hachage restait toujours vide puisqu'elle était dupliqué à chaque fork :-( Et là, je me suis rappelé des cours de système et des communications entre processus! Le plus simple pour un truc comme le mien serait peut être les tubes :
 

tant que 1 faire
   si demande connexion alors
       fork
       si fils alors
            traiter_connexion
       fsi
  fsi
  tant que (données dans tube) faire
      lire dans tube
      ajouter dans la table de hachage
  ftant
ftant


 
avec dans traiter_connexion une écriture dans le tube des données à ajouter dans la table.
 
Par contre, si je créé juste un tube ou le fils écrit et le père lit, il me faut un tube par fork? Ou le même suffit? Je me rappelle plus comment ca se passe au niveau des accès concurrents en écriture??
 
Et puis là, je risque de faire attendre des connexions si je reste trop longtemps dans mon deuxième tant que.
 
Merci d'avance pour votre aide! :)


Message édité par _p1c0_ le 03-01-2006 à 14:13:02
Reply

Marsh Posté le 05-01-2006 à 09:37:04    

Bonjour à tous,
 
en faisant mes recherches, j'ai fini par en arriver aux pthreads qui apparament posent moins de problèmes pour faire ce que je veux...
 
Un semaphore pour les écritures/lectures dans ma table de hachage me permettra de régler les problèmes de concurrence. Maintenant, il y a encore quelque chose qui mé gène...
 
J'ai récupéré un code pour d'exemple de clientserver qui semble être censé gérer le multi client avec un thread par connexion. Par contre, quand je rallonge le temps de traitement avec un sleep dans la fonction exécutée par le thread, les clients sont obligés d'attendre avant que leur demande soit traitée...
 
Je vous mets le bout de code qui correspond :
 

Code :
  1. while (1) {
  2.          printf("SERVER: Waiting for contact ...\n" );
  3.        
  4.          if (  (sd2=accept(sd, (struct sockaddr *)&cad, &alen)) < 0) {
  5.                       fprintf(stderr, "accept failed\n" );
  6.                               exit (1);
  7.  }
  8.  pthread_create(&tid, NULL, serverthread, (void *) sd2 );
  9.      }


 
où sd est la socket sur laquelle on écoute...
 
Au premier abord ca me paraissait plutot bien mais ca n'a pas l'air de marcher comme je le pensais. Donc je voudrais savoir s'il est bien possible de gérer le multi client avec les pthreads?  
 
Merci d'avance pour vos réponses! :)

Reply

Marsh Posté le 05-01-2006 à 13:06:18    

_p1c0_ a écrit :

Donc je voudrais savoir s'il est bien possible de gérer le multi client avec les pthreads?


Oui, bien sûr, avec select() ou poll().


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 05-01-2006 à 17:22:12    

Emmanuel Delahaye a écrit :

Oui, bien sûr, avec select() ou poll().


 
Je viens de regarder select mais j'ai peur de pas avoir bien compris. Dans le select, on passe un ensemble de descripteurs mais si mon serveur est en écoute sur un seul port, il n'y a qu'un descripteur non?  
 
Moi mon serveur ne répond même pas au client là, il récupère juste les données pour les traiter de son coté. La seule chose qui prend du temps, c'est le décryptage des données recues. Ca vaut vraiment le coup de mettre tout ca en place? Y a pas un moyen plus simple en gardant le fork?
 
Merci pour vos réponses :)

Reply

Marsh Posté le 06-01-2006 à 08:58:26    

J'ai approfondi mes recherches et je pense avoir trouvé une idée. Avant de me lancer dans le code, je voudrais avoir votre avis...
 

Code :
  1. ouverture de la socket sl en écoute
  2. mettre la socket dans un ensemble E
  3. select sur l'ensemble E
  4. si demande connexion
  5.   create_thread avec en paramètre la socket sl
  6. fsi


 
et c'est mon thread qui s'occupe de faire un accept...
 
Est ce réalisable? Moi ca me parait pas mal mais il ya peut être quelque chose qui m'échappe???
 
Merci :)

Reply

Marsh Posté le 06-01-2006 à 09:09:07    

_p1c0_ a écrit :


Code :
  1. ouverture de la socket sl en écoute
  2. mettre la socket dans un ensemble E
  3. select sur l'ensemble E
  4. si demande connexion
  5.   create_thread avec en paramètre la socket sl
  6. fsi




C'est bien d'écrire l'algo avant de foncer dans code.
 
Pourquoi 'si en écoute' ?
Je ne sais pas trop ce que tu appelles 'ensemble E'...


ouverture de la socket s_srv
mettre la socket s_srv en ecoute sur un port donné.
FAIRE
   select sur cette socket
   SI demande connexion
      accepter s_cli
      create_thread avec en paramètre la socket s_cli
   FIN SI
TOUJOURS


 
Le contenu du thread dépend de UDP/TCP...


Message édité par Emmanuel Delahaye le 06-01-2006 à 09:11:35

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-01-2006 à 09:30:34    

Ok, désolé c'était pas si mais c'était un L miniscule.
 
Ce qui me pose problème dans ton algo, c'est au niveau du accept. Avec les threads, la les variables sont partagées si j'ai bien compris... Donc si j'accepte la connexion toujours dans la même variable, ca va pas poser problème?
 
Merci pour ton aide

Reply

Marsh Posté le 06-01-2006 à 10:03:41    

_p1c0_ a écrit :

Ce qui me pose problème dans ton algo, c'est au niveau du accept. Avec les threads, la les variables sont partagées si j'ai bien compris... Donc si j'accepte la connexion toujours dans la même variable, ca va pas poser problème?


Ben non. Tu fais ça dans une variable locale... Quand la connexion se termine, le thread aussi, et la mémoire est libérée automatiquement.
 
Par contre, les données partagées (socket du serveur ? config diverses... etc.) doivent être définies dans la mémoire statique du serveur (une structure) et l'adresse passée en paramètre aux threads. On est pas des barbares, on utilise pas les globales sauvages...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-01-2006 à 10:03:41   

Reply

Marsh Posté le 06-01-2006 à 10:09:23    

Emmanuel Delahaye a écrit :

Ben non. Tu fais ça dans une variable locale... Quand la connexion se termine, le thread aussi, et la mémoire est libérée automatiquement.
 
Par contre, les données partagées (socket du serveur ? config diverses... etc.) doivent être définies dans la mémoire statique du serveur (une structure) et l'adresse passée en paramètre aux threads. On est pas des barbares, on utilise pas les globales sauvages...


 
Ok, je te remercie pour tes explications. Je vais essayer de coder tout ça et si ca se passe mal, je reviendrais faire un petit tour ici :-)

Reply

Sujets relatifs:

Leave a Replay

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