Si je mettais tout dans le main ce serait:
int main()
{
sf::SocketUDP socket;
unsigned short port = 4567;
if(!socket.Bind(port))
{
cout << "Impossible d'ecouter le port !" << endl;
}
sf::IPAddress ip = sf::IPAddress::GetLocalAddress();
cout << "Votre adresse est: " << ip.ToString() << endl;
unsigned int nbreClients = 0;
unsigned short portclient = 0;
sf::IPAddress clients[10];
sf::Packet p;
sf::IPAddress sender;
while(1)
{
switch(socket.Receive(p, sender, portclient))
{
case sf::Socket::Done:
for(int i = 0; i < nbreClients; i++)
{
if(clients[i] == sender)
{
for(int i = 0; i < nbreClients; i++)
{
socket.Send(p, clients[i], 4568);
}
}
}
cout << "Nouveau client connecte(" << nbreClients << "): " << sender.ToString() << endl;
nbreClients = nbreClients + 1;
clients[nbreClients-1] = sender;
//broadcast
for(int i = 0; i < nbreClients; i++)
{
socket.Send(p, clients[i], 4568);
}
break;
case sf::Socket::Disconnected:
cout << "Client deconnecte: " << sender.ToString() << endl;
break;
case sf::Socket::Error:
cout << "Erreur de " << sender << endl;
break;
default:
break;
}
p.Clear();
}
socket.Close();
return 0;
}
mais je ne pense pas que ça vienne du serveur (directement en tous cas). En fait le client se contente de faire ceci:
un thread pour recevoir les paquets
//Thread se chargeant de la réception de paquets
void networkLoop(void* data)
{
TankMania *tankmania = static_cast<TankMania*>(data);
sf::SocketUDP socket;
sf::Packet packetin;
TankManiaPacket p;
packetin.Clear();
unsigned short portenvoyeur;
sf::IPAddress ipenvoyeur;
if(!socket.Bind(4568))
{
cout << "Impossible de binder le socket sur 4568" << endl;
tankmania->writeToLog("Impossible d'écouter le port 4568");
}
while(run)
{
if(socket.Receive(packetin, ipenvoyeur, portenvoyeur) == sf::Socket::Done)
{
packetin >> p;
cout << "Nouveau message: " << p.nom << " " << p.position.X << " " << p.position.Y << " " << p.position.Z << " " << p.rotation.X << " " << p.rotation.Y << " " << p.rotation.Z << "\r";
if(p.nom != tankmania->getLocalPlayer()->getName())
{
tankmania->addPlayer(p.nom, true);
tankmania->getJoueur(p.nom)->getTank()->getNode()->setPosition(p.position);
tankmania->getJoueur(p.nom)->getTank()->getNode()->setRotation(p.rotation);
}
}
}
tankmania->writeToLog("Fin du thread réseau");
}
et une fonction pour les envoyer
void TankMania::sendPacketToServer(Joueur *joueur)
{
packetout.Clear();
TankManiaPacket p;
p.position = joueur->getTank()->getNode()->getPosition();
p.rotation = joueur->getTank()->getNode()->getRotation();
p.nom = joueur->getName();
packetout << p;
socket.Send(packetout, ip, port);
}
Alors comme c'est un jeu j'appelle la fonction d'envoi de paquet à chaque tour de boucle. Quand je suis sur la même machine en client et serveur ça marche très bien mais dès que je lance le serveur sur un autre ordinateur sf::Socket::error est renvoyé au bout de quelques paquets échangés.
Finalement je me demande si ce n'est pas lié au fait que j'envoie trop de paquets (deux pcs à 60 fps) et que je ne me fais pas une sorte de déni de service ?
Ca ne me semble pas énorme non plus 60 paquets. J'ai testé une solution radicale qui consiste à limiter l'envoi à un paquet par seconde et étrangement ça marche très bien (en fait j'arrive à lancer le jeu sur les deux machines plusieurs minutes et les paquets transitent normalement). Mais dans la console du serveur des sf::Socket::error sont toujours affichés bien que moins nombreux. Est ce que ça viendrait uniquement d'un trop grand nombre de paquets échangés ?
Merci