Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Socket : réaction bizarre ? receive bloquant après un wait...  (Lu 2193 fois)

0 Membres et 1 Invité sur ce sujet

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
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 ?
« Modifié: Mai 09, 2012, 06:06:07 am par neo007 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Socket : réaction bizarre ? receive bloquant après un wait...
« Réponse #1 le: Mai 09, 2012, 08:21:17 am »
Citer
J'utilise peut-être pas correctement les sockets ?
Sûrement :)
Donc faudrait voir plus de code.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : Socket : réaction bizarre ? receive bloquant après un wait...
« Réponse #2 le: Mai 09, 2012, 01:25:59 pm »
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)
« Modifié: Mai 09, 2012, 02:07:44 pm par neo007 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Socket : réaction bizarre ? receive bloquant après un wait...
« Réponse #3 le: Mai 09, 2012, 02:12:27 pm »
Si j'ai bien compris : ça affiche "1" tout de suite, puis ça bloque, et ça affiche "2" quand le client se déconnecte. C'est ça ?

Pour le erase : il faut faire it = list.erase(it) (et du coup ne faire le ++it que si tu n'as pas appelé erase).
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : Socket : réaction bizarre ? receive bloquant après un wait...
« Réponse #4 le: Mai 09, 2012, 10:43:05 pm »
EDIT

Ne cherche plus, l'erreur venait d'EncryptedPacket... Une erreur interne dans ces méthodes survenait (onSend et onReceive) alors le client envoyait un Packet erroné et là le serveur aimait pas trop ça et la fonction receive devenait bloquante.

Ça je ne sais pas pourquoi, mais elle le devient quand le Packet a une erreur (je parle de l'encryptage des données donc)

Merci de ton précieux temps, car je sais que tu en as pas beaucoup malgré les 24 heures d'une journée, c'est jamais assez ! ;D ;)
« Modifié: Mai 09, 2012, 11:25:12 pm par neo007 »