Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: [Résolu] Problème avec les threads  (Lu 1738 fois)

0 Membres et 1 Invité sur ce sujet

DexArio

  • Newbie
  • *
  • Messages: 16
    • Voir le profil
[Résolu] Problème avec les threads
« le: Août 29, 2014, 10:53:24 am »
Bonjour,

Je travaille actuellement sur un petit jeu en réseau, utilisant une architecture client/serveur et le protocole TCP. Mon problème vient de la partie serveur: j'utilise un thread par client mais le problème vient du fait que lorsque je lance un nouveau thread de client (lorsque il y a une nouvelle connexion, car j'utilise un thread par client pour communiquer), il est automatiquement arrêté car il est stocké dans un vector et comme stipulé dans lu tutoriel concernant les threads, si un thread n'a plus son instance, il est détruit. Je stocke mes threads dans un vector car le nombre de joueurs est variable, je pense que le problème vient de là, mais du coup, je me demande comment stocker des threads sans qu'ils soient détruits. Voici mon code:

Voici le vector:

vector<ClientThread*> clientThreads;

La structure ClientThread:

struct ClientThread
{
   int playerID;
   sf::Thread *commThread; //Communication thread
};

Et la fonction Listen() qui s'occupe d'écouter sur un certain port et de gérer les nouvelles connexions (donc de lancer les ClientThreads). Cette fonction n'est pas exécutée dans le main thread mais dand un autre thread. J'ai essayé de garder l'essentiel.

void Listen()
{
   sf::TcpListener listener;

   if (listener.listen(port) != sf::TcpListener::Done)
   {
      cout << "Error while attempting to listen on port " << port << endl;
      error = true;
      return;
   }

   int idCounter = 0;

   while (!stop)
   {
      //If the server is full, we will not accept more clients
      if (clients.size() > 3)
      {
         while (clients.size() > 3)
            Sleep(100);
      }

      Client client;

      listener.accept(client.socket);
      cout << "Initializing new client..." << endl;
      client.ID = idCounter;
      clients.push_back(&client);

      /*Du code pas important...*/

   next:;
      //Launching communication thread
      clientThreads.push_back(new ClientThread());
      clientThreads[clientThreads.size() - 1]->playerID = idCounter;
      clientThreads[clientThreads.size() - 1]->commThread = new sf::Thread(&Communicate, idCounter);
      clientThreads[clientThreads.size() - 1]->commThread->launch();

      idCounter++;
      cout << "New client successfuly connected" << endl;
   }
}

Voici comment sont stockés les clients:

vector<Client*> clients;

Et la structure:

struct Client
{
   sf::TcpSocket socket;
   int ID;
   string color;
   sf::Vector2i counterPos;
};
 
Et voici la fonction Communicate, qui sert à communiquer avec le client:

void Communicate(int id)
{
   sf::Packet p;

   //Sending connection info
   p << GetClientWithID(id)->color << GetClientWithID(id)->counterPos.x << GetClientWithID(id)->counterPos.y;
   GetClientWithID(id)->socket.send(p); //<-------- Ce packet est bien envoyé

   p.clear();

   while (!stop)
   {
      if (GetClientWithID(id) == NULL)
         return;

      if (GetClientWithID(id)->socket.receive(p) != sf::Socket::Done) //<----------- Perte de connexion ici, avec sf::Socket::Error
      {
         cout << "Client " << id << " lost connection" << endl;
         RemoveClientWithID(id);
         return;
      }
      else
      {
         BroadcastPacket(p, id);
         p.clear();
      }
   }
}

Remarquez les commentaires que j'ai mis qui stipulent où est l'erreur et où elle n'est pas.

Je tiens à préciser que tout le code est contenu dans un seul fichier Main.cpp. Les vectors sont donc des variables globales. Ce n'est pas très propre mais à vrai dire, je ne pensais pas que le serveur allait être aussi gros (il n'y a pas que ça comme code) donc j'ai fait comme cela et je me rends compte que je me suis un peu planté sur ce point. Mais au moins, la prochaine fois, je le saurai et je ferai quelque chose de plus propre.

Merci.
« Modifié: Octobre 08, 2014, 07:35:24 pm par DexArio »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème avec les threads
« Réponse #1 le: Août 29, 2014, 10:58:50 am »
Puisque tout est alloué dynamiquement, ce n'est pas un problème de durée de vie. Enfin si, mais pas sur le thread.

C'est plus bête que ça :
Client client;
// ...
clients.push_back(&client);

Là tu mets dans ton vector un pointeur vers un objet local à une fonction. Dès la prochaine accolade fermante, ton objet sera détruit et l'élément correspondant dans le vector pointera vers du caca.
Laurent Gomila - SFML developer

TheKingArthur

  • Invité
Re : Problème avec les threads
« Réponse #2 le: Août 29, 2014, 11:49:56 am »
Vers du caca ?
à ouais quand même...