Bonjour, je code actuellement un petit jeu en utilisant la SFML.
Ayant fait divers entraînements par le passé pour maîtriser au mieux cette librairie, j'ai décidé cette fois de me lancer dans la programmation Réseau.
Edit important : j'utilise SFML 2.0 avec code::blocks sur Windows 7, j'avais ommis de le préciser.Le choix du TCP m'a semblé le plus simple à mettre en place pour apprendre le fonctionnement réseau (il n'est pas forcément le plus adapté à mon projet, mais ce n'est qu'un entraînement).
Mon problème : Le serveur et le client sont deux applications différentes. Lorsque le client tente de se connecter au serveur, tout fonctionne parfaitement (le serveur affiche le message de connexion, renvoie 1 au client pour lui indiquer qu'il est prêt à communiquer). Une fois la connexion établie, l'actualisation des positions est totalement hasardeuse. C'est à dire que j'obtient des positions qui ne rentrent même pas dans un int... le jeu saccade et la position est rafraîchie toutes les 10sec (et est en plus fausse).
Tests effectués : Changer de port, mettre 1 packet pour la reception et 1 pour l'envoi, tester en ligne (via hamachi, avec la bonne ip bien entendu, l'autre client se connecte également parfaitement mais l'erreur est exactement la même qu'en local.)
Le code coté serveur :
Serveur.hpp:#include <SFML/Network.hpp>
#include <iostream>
#include <sstream>
class Serveur
{
public:
Serveur();
void initServeur();
void attenteConnexions();
void recevoirDonnees();
void envoyerDonnees();
~Serveur();
private:
int nbJoueurs;
int nbJoueursMax;
int port;
int test;
bool client1Connecte;
bool client2Connecte;
int delay1;
int delay2;
sf::TcpListener listener;
sf::TcpSocket socket;
sf::TcpSocket client1;
sf::TcpSocket client2;
sf::TcpSocket clientMax;
sf::Packet packet1;
sf::Packet packet1bis;
sf::Packet packet2;
sf::Packet packet2bis;
sf::Packet packetMax;
// Infos joueur 1
int posX1;
int posY1;
//Infos joueur 2
int posX2;
int posY2;
};
Serveur.cpp:#include "serveur.hpp"
Serveur::Serveur(): nbJoueurs(0), nbJoueursMax(2), port(15230), test(0), client1Connecte(false), client2Connecte(false), delay1(0), delay2(0)
{
}
void Serveur::initServeur()
{
std::cout << "[Serveur] Initialisation du serveur sur le port " << port << " ..." << std::endl;
socket.setBlocking(false);
listener.setBlocking(false);
client1.setBlocking(false);
client2.setBlocking(false);
if(listener.listen(port) != sf::Socket::Done)
{
std::cout << "[Erreur] Erreur lors de l'initialisation du Listener sur le port " << port << std::endl;
std::cout << "[Aide] Le port est probablement ferme ou deja utilise" << std::endl;
}
else
{
std::cout << "[Serveur] serveur ON ! Port utilise : " << port << std::endl;
std::cout << "[Serveur] en attente de connexions..." << std::endl;
}
}
void Serveur::attenteConnexions()
{
if(!client1Connecte)
{
if(listener.accept(client1)==sf::Socket::Done)
{
packet1 << 1;
client1.send(packet1);
std::cout << "Client 1 s'est connecte" << std::endl;
nbJoueurs++;
client1Connecte = true;
std::cout << "Nombres de joueurs : " << nbJoueurs << "/" << nbJoueursMax << std::endl;
}
}
if(!client2Connecte)
{
if(listener.accept(client2)==sf::Socket::Done)
{
packet2 << 1;
client2.send(packet2);
std::cout << "Client 2 s'est connecte" << std::endl;
nbJoueurs++;
client2Connecte = true;
std::cout << "Nombres de joueurs : " << nbJoueurs << "/" << nbJoueursMax << std::endl;
}
}
if(nbJoueurs == nbJoueursMax)
{
if(listener.accept(clientMax)==sf::Socket::Done && client1Connecte && client2Connecte)
{
std::cout << "Un jouer tente de se connecter alors que le max est atteint" << std::endl;
packetMax << -1;
clientMax.send(packetMax);
}
}
}
void Serveur::recevoirDonnees()
{
if(client1Connecte)
{
if(client1.receive(packet1) == sf::Socket::Done)
{
packet1 >> posX1 >> posY1;
delay1 = 0;
}
else
{
delay1++;
}
if(delay1 > 1000000)
{
std::cout << "Client 1 est deconnecte" << std::endl;
nbJoueurs--;
client1Connecte = false;
delay1 = 0;
}
}
if(client2Connecte)
{
if(client2.receive(packet2) == sf::Socket::Done)
{
packet2 >> posX2 >> posY2;
delay2 = 0;
}
else
{
delay2++;
}
if(delay2 > 1000000)
{
std::cout << "Client 2 est deconnecte" << std::endl;
nbJoueurs--;
client2Connecte = false;
delay2 = 0;
}
}
}
void Serveur::envoyerDonnees()
{
if(client1Connecte)
{
if(client2Connecte)
{
packet1 << posX2 << posY2;
client1.send(packet1);
}
}
if(client2Connecte)
{
if(client1Connecte)
{
packet2 << posX1 << posY1;
client2.send(packet2);
}
}
}
Serveur::~Serveur()
{
}
Le code coté client (je ne vous mets pas la gestion des évenements etc, juste
l'unique partie qui touche au réseau
reseau.hpp:#include <SFML/Graphics.hpp>
#include <SFML/Network.hpp>
#include <iostream>
#include <sstream>
class Reseau
{
public:
Reseau();
void initClient();
void chargerRessources();
void connexionServeur();
void envoyerInfos(int persoX, int persoY);
void recevoirInfos();
void afficherAutres(sf::RenderWindow &app);
~Reseau();
private:
//Partie Réseau
int test;
int port;
int canSend;
sf::TcpSocket socket;
sf::Packet packet;
sf::IpAddress adresse;
//Infos Joueur 2
int posX2;
int posY2;
//Partie Graphique
sf::Texture persoTile;
sf::Sprite basPause;
};
reseau.cpp:#include "reseau.hpp"
Reseau::Reseau() : port(15230), canSend(0)
{
}
void Reseau::initClient()
{
test = 50;
port = 15230;
socket.setBlocking(false);
}
void Reseau::chargerRessources()
{
persoTile.loadFromFile("resources/personnages/0.png");
basPause.setTexture(persoTile);
basPause.setTextureRect(sf::IntRect(0, 0, 32, 48));
}
void Reseau::connexionServeur()
{
if(canSend == 0)
{
socket.connect("127.0.0.1",port);
if(socket.receive(packet) == sf::Socket::Done)
{
packet >> canSend;
}
if(canSend == -1)
{
}
if(canSend == 1)
{
}
}
}
void Reseau::envoyerInfos(int persoX, int persoY)
{
if(canSend == 1)
{
packet << persoX << persoY;
socket.send(packet);
}
}
void Reseau::recevoirInfos()
{
if(canSend == 1)
{
if(socket.receive(packet) == sf::Socket::Done)
{
packet >> posX2 >> posY2;
std::cout << posX2 << " : " << posY2 << std::endl;
basPause.setPosition(posX2, posY2-16);
}
}
}
void Reseau::afficherAutres(sf::RenderWindow &app)
{
if(canSend == 1)
{
app.draw(basPause);
}
}
Reseau::~Reseau()
{
}
Dans le main, toutes les fonctions sont executées, dans cet ordre pour le client :
map.test(app);
perso.afficherPerso(app);
perso.afficherCheveux(app);
perso.centrerVue(app,vue);
reseau.connexionServeur();
reseau.envoyerInfos(perso.getPosX(), perso.getPosY());
reseau.recevoirInfos();
reseau.afficherAutres(app);
if(isFocused)
{
perso.bougerPerso();
}
les fonctions getPos, on ne peut plus simples:
int Perso::getPosX()
{
return posX;
}
int Perso::getPosY()
{
return posY;
}
et pour le serveur :
int main()
{
int continuer = true;
Serveur serveur;
serveur.initServeur();
while(continuer)
{
serveur.attenteConnexions();
serveur.recevoirDonnees();
serveur.envoyerDonnees();
}
}
Si vous avez besoin d'autres informations, je répondrai au plus vite possible.
En espérant que vous m'aiderez à trouver mon erreur.
CookieSpirit.