Bonjour à tous et à toutes :)
J'utilises les sockets et les packets fourni et il m'est impossible de les gérer correctement, car j'obtiens un gèle au niveau du receive en faisant pourtant un selector.wait() juste avant...
Voici ce qui se passe :
selector.wait() est dégelé, car le client envoie un packet. Ensuite, j'ai une condition qui appelle une fonction identification(client);
Voici juste le début et la fin de cette fonction :
bool ConnectionServer::identification(TcpSocket& client)
{
EncryptedPacket packet;
cout<<"1";
if(client.receive(packet) == Socket::Done)
cout<<"Packet recu";
else
{
cout<<"2";
return false;
}
}
T'es même chanceux Laurent, tu sais déjà ce qui se passe dans un EncryptedPacket ;D
Bon, ce qui est intéressant dans ce code c'est simple : la console m'affiche : 12.
C'est pas normal, car les combinaisons possibles d'affichage devrait être "1packet recu" ou "12" en considérant que la fonction receive ne bloque pas étant donné qu'on est dans une boucle wait.
Ce qui arrive : quand le client se connecte et envoie son premier packet, le console affiche seulement le "1", ce qui veut dire qu'elle reste bloquée sur le receive. Ensuite, lorsque le client quitte, ça affiche le 2 (comme quoi qu'ya eu une erreur ou une déconnection).
Comment se fait-il que la fonction wait débloque (normal on envoie des données) et que la fonction receive reste bloquée alors que ya justement des données à lire !? ???
Sans compter que le client m'affiche lui dans sa console un Status Error (3 qui correspond à Error, testé en cout<<Socket::Error pour être sûr) lorsqu'il envoie son packet (cout<<socket.send(packet); donc), mais pourtant le serveur reçoit quelque chose puisque le wait rend la main sauf qu'après l'avoir rendu, la méthode receive bloque...
J'utilise peut-être pas correctement les sockets ? une erreur au niveau d'encryptedpacket c'est possible ?
D'accord, si tu insistes... ::) Voici ma fonction run du serveur (il est clair que l'erreur vient du serveur et non du client puisque le client fait juste ce que j'ai écrit plus haut : connection, envoie d'un packet et ensuite sensé recevoir un packet (donc un receive bloquant, c'est juste un client de test) :
while(m_isValid)
{
if(m_selector.wait())
{
if(m_selector.isReady(m_listener))
{
TcpSocket* client = new TcpSocket;
EncryptedPacket packet;
cout<<client->receive(packet);
if (m_listener.accept(*client) == sf::Socket::Done)
{
m_clients.push_back(client);
m_selector.add(*client);
}
}
else
{
cout<<"new data";
for(list<TcpSocket*>::iterator it = --m_clients.end(); it != --m_clients.begin(); --it)
{
TcpSocket& client = **it;
if(m_selector.isReady(client))
{
if(identification(client))
//Envoie d'un packet : celui que le client attend
else
//On arrive toujours ici, identification bloque, puis renvoit false quand on se déconnecte
}
}
}
}
}
bool ConnectionServer::identification(TcpSocket& client)
{
EncryptedPacket packet;
cout<<"1";
if(client.receive(packet) == Socket::Done)
{
cout<<"Packet recu";
DataConnection dataConnection;
if(packet >> dataConnection)
{
//Trop de ligne inutile donc couper (on appel Mysql et on vérifie l'identification)
//De toute façon, on n'arrive jamais ici puisque ça bloque avant...
}
else
return false;
}
else
{
cout<<"2";
return false;
}
}
petit rappel simple : la fonction receive bloque et pourtant elle est appelée dans la boucle wait. Ça affiche toujours le fameux "12" et "packet recu" lui ne s'affiche jamais.
Merci de ton aide et bonne journée ! ;D
ps. L'itération à l'envers sans utiliser les reverse_iterator est simplement pour éviter un problème d'invalidité de l'itérateur courant après un list.erase(it); Quand on fait la boucle à l'envers, l'itérateur reste valide :) (du moins, ça fonctionne sans perte et sans erreur)