Salut !
Je suis nouveau ( je n'ai même pas encore fait le tour du forum, s'il y a une section "Présentation" j'irai faire un tour ) et j'ai un soucis avec le module réseau ( ou mon code ? ) .
Le soucis est que, mon code "fonctionne" très bien, cependant pour recevoir un message ( type string mais peu importe ) je suis obligé de l'envoyer deux fois !
Serveur :
#include <iostream>
#include <SFML/Network.hpp>
using namespace std;
using namespace sf;
TcpListener listener;
TcpSocket client;
SocketSelector selector;
void send(string msg)
{
Packet p;
p << msg;
client.send(p);
}
int main()
{
if ( listener.listen(10001) != Socket::Done )
{
cout << "Impossible de lancer le serveur ..." << endl;
return 0;
}
selector.add(listener);
while ( true )
{
if ( selector.wait(seconds(10)) )
{
if ( selector.isReady(listener) )
{
if ( listener.accept(client) == Socket::Done )
{
cout << "Client accepté !" << endl;
selector.add(client);
}
}
else if ( selector.isReady(client) )
{
Packet p;
if ( client.receive(p) == Socket::Disconnected )
{
cout << "Client déconnecté !" << endl;
selector.remove(client);
}
else if ( client.receive(p) == Socket::Done )
{
string msg;
p >> msg;
cout << "Message du client : " << msg << endl;
// Je suis obligé d'envoyer 2 fois le message pour le recevoir sur le client !!
send("De rien, cela me touche !");
send("De rien, cela me touche !");
}
}
}
}
return 0;
}
Client :
#include <iostream>
#include <SFML/Network.hpp>
using namespace std;
using namespace sf;
TcpSocket s;
SocketSelector selector;
void send(string msg)
{
Packet p;
p << msg;
s.send(p);
}
int main()
{
if ( s.connect("localhost", 10001) != Socket::Done )
{
cout << "Impossible de se connecter au serveur ..." << endl;
return 0;
}
selector.add(s);
// Je suis obligé d'envoyer 2 fois le message pour le recevoir sur le serveur !!
send("Merci de m'accueillir sur le serveur !");
send("Merci de m'accueillir sur le serveur !");
while ( true )
{
if ( selector.wait(seconds(10)) )
{
if ( selector.isReady(s) )
{
Packet p;
if ( s.receive(p) == Socket::Disconnected )
{
cout << "Déconnecté du serveur ..." << endl;
return 0;
}
if ( s.receive(p) == Socket::Done )
{
string msg;
p >> msg;
cout << "Message du serveur : " << msg << endl;
}
}
}
}
return 0;
}
J'utilise CodeBlocks sous Ubuntu 14.04.2 et j'ai bien lier les dépendances ( dans l'ordre : sfml-network, sfml-system ).
Une idée ? Je n'ai rien trouvé sur le forum qui puisse m'aider !
Problème résolu !
Serveur :
Packet p;
Socket::Status status = client.receive(p);
if ( status == Socket::Done )
{
string msg;
p >> msg;
cout << "Message du client : " << msg << endl;
// Je suis obligé d'envoyer 2 fois le message pour le recevoir sur le client !!
send("De rien, cela me touche !");
}
else if ( status == Socket::Disconnected )
{
cout << "Client déconnecté !" << endl;
selector.remove(client);
}
Client :
Packet p;
Socket::Status status = s.receive(p);
if ( status == Socket::Done )
{
string msg;
p >> msg;
cout << "Message du serveur : " << msg << endl;
}
else if ( status == Socket::Disconnected )
{
cout << "Déconnecté du serveur ..." << endl;
return 0;
}
Je ne peux pas expliquer pourquoi ça fonctione comme ça ( du moins en détail ) mais j'ai compris que ça venait du fait de la fonction .receive(packet); .
Si quelqu'un peut m'expliquer en détail pourquoi ça fonctionne à présent, je prends !
if ( client.receive(p) == Socket::Disconnected )
{
cout << "Client déconnecté !" << endl;
selector.remove(client);
}
else if ( client.receive(p) == Socket::Done )
Le premier paquet reçu sera intercepté par la fonction receive du premier if. Comme le status n'est pas == Socket::Disconnected le programme avance au else if, et le 2nd receive bloque en attente d'un paquet. Et donc quand tu en envoies 2 ton 2eme receive reçoit le 2eme paquet.
Là dans ta correction c'est bien : tu reçois un paquet, et suivant le statut de cette réception (réussie, déconnexion, ...) tu traites ou pas le paquet reçu.