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.