maitretarot-devel-fr
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Maitretarot-devel-fr] sockets, serveurs, fork, POSIX...


From: Olivier Péningault
Subject: Re: [Maitretarot-devel-fr] sockets, serveurs, fork, POSIX...
Date: 03 Feb 2003 22:53:10 +0100

le lun 03-02-2003 à 21:25, Yves Mettier a écrit :
> Ici, nous avons un cas particulier. Une fois le fork realise, il n'y a plus de
> communication entre le pere et le fils. Sauf eventuellement des spectateurs 
> qui
> viendraient s'y connecter, et c'est la la difficulte.
> C'est justement pour cela que je prefere la solution fork: chaque serveur 
> devient
> vraiment independant puisqu'il l'est deja au niveau algorithmique.
Oui, mais il reste le problème du spectateur qui veut assister à
plusieurs parties....
En fait, je ne pense pas que ce soit un cas particulier; voici ce que
permettrait un select() :

Les connections, lorsqu'elles sont acceptées, sont rangées dans une file
d'attente, le temps que le joueur rejoigne une partie. Ensuite, ce
descripteur de socket est mis dans partie[i].joueur[j].
Si un spectateur veut assister à cette partie i, il est placé dans la
file d'attente (à la connection), puis une fois son choix exprimé, il va
dans partie[i].spectateur[k]...

La boucle du jeu serait un truc du genre :

while (42 > 1) {

 FD_ZERO (ecoute);

 // nouvelle connection ?
 FD_SET (socket_ecoute_nouveau_joueur,ecoute);
 max = socket_ecoute_nouveau_joueur;
 // joueurs en attente
 for (i=0;i<nbattente;i++) {
  FD_SET (attente[i].sock,ecoute);
  if (attente[i].sock > max)
   max = attente[i].sock;
 }

 // pour chaque jeu en cours ...
 for (i=0;i<nbparties;i++) {

  // joueurs de la partie i
  for (j=0;j<partie[i].nbjoueurs;j++) {
   FD_SET (partie[i].joueur[j].sock,ecoute);  
   if (partie[i].joueur[j].sock > max) 
    max = partie[i].joueur[j].sock;
  } // for(j...

  // spectateurs de la partie i
  for (j=0;j<partie[i].nbspectateurs;j++) {
   FD_SET (partie[i].spectateur[j].sock,ecoute);
   if (partie[i].spectateur[j].sock > max) 
    max = partie[i].spectateur[j].sock;
  } // for(j...
 } // for(i...

 toto = select (max+1,ecoute,NULL,NULL,timeout);

 if (toto > 0) {
  if (FD_isset(socket_ecoute_nouveau_joueur,ecoute) {
  // nouvelle connection
  // accept() puis mise en file d'attente
  } // if FD_ISSET (socket_ecoute_nouveau_joueur,ecoute)

  for (i=0;i<nbattente;i++) {
   if (FD_ISSET (attente[i].sock,ecoute)) {
   // un client en attente veut faire qqchose.
   // c'est ici qu'on effectue le traitement nécessaire

   } // if (FD_ISSET (attente[i].sock,ecoute))
  } // for (i=0;i<nbattente;i++)

  // Que se passe-t-il dans les parties ???
  for (i=0;i<nbparties;i++) {

   // des joueurs jouent peut etre...
   for (j=0;j<partie[i].nbjoueurs;j++) {
    if (FD_ISSET (partie[i].joueur[j].sock,ecoute) {
     // ce joueur a effectué une action.
     // on voit s'il en a le droit, et si oui, ok
     // sinon on refuse...

    } // if (FD_ISSET (partie[i].joueur[j].sock,ecoute)
   } // for (j=0;j<partie[i].nbjoueurs;j++)

   // des spectateurs se manifestent...
   for (j=0;j<partie[i].nbspectateurs;j++) {
    if (FD_ISSET (partie[i].spectateur[j].sock,ecoute)) {
     // un spectateur se manifeste, on voit ce qu'on fait de lui...

    } // if (FD_ISSET (partie[i].spectateur[j].sock,ecoute))
   } // for (j=0;j<partie[i].nbspectateurs;j++)

  } // for (i=0;i<nbparties;i++)

 } // if(toto>0)

} // while

J'espère qu'il y a pas trop de bugs... ;)

A partir de là, c'est super simple d'ajouter des fonctionnalités :
- un spectateur qui change de partie.
- un spectateur parle à un joueur (je ne sais pas si c'est une bonne
idée... :)
- un joueur qui en congratule un autre.
- un joueur qui insulte un adversaire (je ne sais pas si c'est une bonne
idée... :)
- une partie qui s'interrompt -> les joueurs vont en file d'attente.
- mode tournoi : l'ordinateur décide qui joue contre qui, le classement
est simple, et les clients sont facilement dispatchés dans les
différentes parties à chaque ronde.
- affichage du score de toutes les parties pour tous.
- multiplexage de jeu (tarot/belote/poker) en fonction de l'humeur des
joueurs.

> Avant le fork, et apres, dans chaque fils, ce sera evidemment du select.

> Pas de memoire partagee, pas de semaphores, rien de tout cela.
Ok, mais avec un fork, tu n'y couperas pas : il n'y a pas d'autre moyen
ki marche connu (je crois...).

> Rien n'a ete refait pour l'instant, mais par contre, justement, on va tout 
> refaire dans
> le serveur pour prendre en compte le nouveau protocole et certains changements
> structurels:
> - jeu a 3 et a 5 joueurs possible (dans le futur)
> - protocole extensible (on en a assez cause ici-meme avant:)
> - plusieurs parties sur un serveur
> - possibilite de rajouter des spectateurs.
> 
> Moi, je repars de zero sur le serveur, et je repiquerai le peu de code 
> utilisable de
> l'actuel serveur par la suite (les regles du jeu et la config)
> Du coup, si tu veux faire cela, c'est tout facile: on repart de zero!
Si je t'ai convaincu, c'est en cours... ;)
Je pense _sincèrement_ qu'un seul processus + select, c'est idéal. Le
code ci-dessus a peut être l'air pas simple au début, mais c'est je
pense la façon la plus simple de faire tout ce qu'on veut. Sinon, avec
un fork, certaines fonctionnalités ne pourront être implémentées...

a+

olivier






reply via email to

[Prev in Thread] Current Thread [Next in Thread]