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

Auteur Sujet: Problème avec les sélectors.  (Lu 8514 fois)

0 Membres et 3 Invités sur ce sujet

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Problème avec les sélectors.
« Réponse #15 le: Juin 19, 2013, 03:38:42 pm »
Arf purée j'ai des erreurs avec la fonction send par moment et je n'arrive pas à avoir plus de détails à ce sujet avec la SFML, je pense que je vais aller voir si il n'y a pas une autre librairie en c++ semblable au module réseau de la SFML et essayer avec.
Parfois aussi j'ai carrément un blocage.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème avec les sélectors.
« Réponse #16 le: Juin 19, 2013, 03:46:58 pm »
Ca m'arrangerait beaucoup plus si on essayait plutôt de corriger ces erreurs ;)
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Problème avec les sélectors.
« Réponse #17 le: Juin 19, 2013, 03:55:50 pm »
Ok. :) Mais difficile quand on arrive pas à avoir beaucoup d'informations sur ses erreurs.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème avec les sélectors.
« Réponse #18 le: Juin 19, 2013, 03:59:37 pm »
Ca je m'en chargerai. Tout ce qu'il faut, c'est un code complet minimal qui reproduit le problème. C'est pas forcément évident, mais sans ça on ne pourra pas avancer.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Problème avec les sélectors.
« Réponse #19 le: Juin 19, 2013, 04:02:32 pm »
Ok, ok.
Bah écoute déja le problème ne survient pas à chaque exécution, bref, je vais essayer de reproduire le problème avec un code plus petit.

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Problème avec les sélectors.
« Réponse #20 le: Juin 20, 2013, 07:10:46 am »
Bon, je pense avoir trouvé la cause du problème, quand j'envoie plusieurs messages UDP du serveur vers le client, le client ne les reçoit plus au bout d'un moment par contre pas de problème pour les messages TCP, et du client vers le serveur ça marche toujours.
Je remet les 2 codes sources, j'ai modifié celui du client en envoyant les messages dans la boucle, j'ai du rajouté un sleep dans la boucle sinon, j'explose la file TCP.

Code côté serveur :

#include "server.h"
using namespace std;
using namespace sf;
void Server::launch() {
    if (listener.listen(4567) == Socket::Done && socketUDP.bind(4568) == Socket::Done)
        cout<<"Ok"<<endl;
    selector.add(listener);
    selector.add(socketUDP);
    while (true) {
        if (selector.wait()) {
            if (selector.isReady(listener)) {

                TcpSocket *client = new TcpSocket();
                if (listener.accept(*client) == Socket::Done) {
                    cout<<"Client connected"<<endl;
                    selector.add(*client);
                    clients.push_back(client);
                }
            }
            for (unsigned int i = 0; i < clients.size(); i++) {
                if (selector.isReady(*clients[i])) {
                    Packet packet;
                    if (clients[i]->receive(packet) == Socket::Done) {
                        string message;
                        packet>>message;
                        cout<<"Received from client (TCP) : "<<message<<endl;
                        packet.clear();
                        message = "Ceci est un message TCP!";
                        packet<<message;
                        if(clients[i]->send(packet) == Socket::Done)
                            cout<<"Ok"<<endl;
                        else
                            cout<<"Erreur"<<endl;
                    } else {
                        selector.remove(*clients[i]);
                        vector<TcpSocket*>::iterator it;
                        for (it = clients.begin(); it != clients.end();)
                            if (*it ==clients[i])
                                it = clients.erase(it);
                            else
                                it++;
                    }
                }
            }
            if (selector.isReady(socketUDP)) {
                Packet packet;
                IpAddress address;
                unsigned short int port;
                if (socketUDP.receive(packet,address, port) == Socket::Done) {
                    string message;
                    packet>>message;
                    cout<<"Received from client (UDP) : "<<message<<endl;
                    packet.clear();
                    message = "Ceci est un message UDP!";
                    packet<<message;
                    if(socketUDP.send(packet, IpAddress::LocalHost, 4569) == Socket::Done)
                        cout<<"Ok"<<endl;
                    else
                        cout<<"Erreur"<<endl;

                }
            }
        }
    }
}
 

Code côté client :

#include <SFML/Network.hpp>
#include <iostream>
#include <sstream>
using namespace std;
using namespace sf;
int main () {
    TcpSocket clientTCP;
    UdpSocket socketUDP;
    SocketSelector selector;
    if (clientTCP.connect(IpAddress::LocalHost, 4567) == Socket::Done && socketUDP.bind(4569) == Socket::Done)
        cout<<"Ok"<<endl;
    selector.add(clientTCP);
    selector.add(socketUDP);
    while (true) {

        Packet packet;
        string message = "";
        stringstream ss;
        ss<<"Ceci est un message pour test le protocole TCP avec la SFML."<<endl;
        message += ss.str();
        packet<<message;
        if (clientTCP.send(packet) == Socket::Done)
            cout<<"Ok"<<endl;
        else
            cout<<"Erreur"<<endl;
        packet.clear();
        message = "Ceci est un message UDP!";
        packet<<message;
        if (socketUDP.send(packet,IpAddress::LocalHost,4568) == Socket::Done)
            cout<<"Ok"<<endl;
        else
            cout<<"Erreur"<<endl;
        if (selector.wait()) {
            packet.clear();
            message = "";
            IpAddress address;
            unsigned short int port;
            if (selector.isReady(clientTCP)) {
                if (clientTCP.receive(packet) == Socket::Done) {
                    packet>>message;
                    cout<<"Received from server (TCP) : "<<message<<endl;
                }
            }
            if (selector.isReady(socketUDP) == Socket::Done) {

                if (socketUDP.receive(packet, address, port) == Socket::Done) {
                    packet>>message;
                    cout<<"Received from server (UDP) : "<<message<<endl;
                }
            }
        }
        sleep(seconds(1.f));
    }
    return 0;
}
 

« Modifié: Juin 20, 2013, 07:16:56 am par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème avec les sélectors.
« Réponse #21 le: Juin 20, 2013, 07:56:22 am »
Impeccable, je teste ça dès que possible :)

Question : est-ce que tout le code TCP est nécessaire pour reproduire le bug UDP ? Y compris la gestion des clients ?
« Modifié: Juin 20, 2013, 07:59:20 am par Laurent »
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Problème avec les sélectors.
« Réponse #22 le: Juin 20, 2013, 08:08:45 am »
Citer
Question : est-ce que tout le code TCP est nécessaire pour reproduire le bug UDP ? Y compris la gestion des clients ?

Non, tu peux retirer ça du code si tu veux tu verra que le client ne recevra toujours pas les messages UDP.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème avec les sélectors.
« Réponse #23 le: Juin 20, 2013, 08:20:07 am »
Quand je parle de code minimal c'est ça que je veux dire : si je teste je ne veux pas m'embêter avec du code qui n'a rien à voir avec le problème. Si on essaye de régler un problème d'UDP, ça sert à quoi de coller un code qui contient pour moitié du code TCP ? :P

Tu peux me refaire ça vite fait, sans le code TCP ? Et au passage, si tu pouvais me mettre le code du serveur dans un main comme le client, ça m'éviterais d'avoir à retaper les mêmes lignes de code à chaque fois que je reprends ton code ;)
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Problème avec les sélectors.
« Réponse #24 le: Juin 20, 2013, 08:38:00 am »
J'avais simplement oublié de virer le code TCP.
Bref voici le code source rien que avec de l'UDP.

Code côté serveur :

#include <SFML/Network.hpp>
#include <iostream>
using namespace sf;
using namespace std;
int main () {
    UdpSocket socketUDP;
    SocketSelector selector;
    if (socketUDP.bind(4568) == Socket::Done)
        cout<<"Ok"<<endl;
    selector.add(socketUDP);
    while (true) {
        if (selector.wait()) {
            if (selector.isReady(socketUDP)) {
                Packet packet;
                IpAddress address;
                unsigned short int port;
                if (socketUDP.receive(packet,address, port) == Socket::Done) {
                    string message;
                    packet>>message;
                    cout<<"Received from client (UDP) : "<<message<<endl;
                    packet.clear();
                    message = "Ceci est un message UDP!";
                    packet<<message;
                    socketUDP.send(packet, IpAddress::LocalHost, 4569);
                }
            }
        }
    }
    return 0;
}

 

Code côté client :

#include <SFML/Network.hpp>
#include <iostream>
#include <sstream>
using namespace std;
using namespace sf;
int main () {
    UdpSocket socketUDP;
    if (socketUDP.bind(4569) == Socket::Done)
        cout<<"Ok"<<endl;
    SocketSelector selector;
    selector.add(socketUDP);

    while (true) {
        Packet packet;
        string message = "Ceci est un message UDP!";
        packet<<message;
        socketUDP.send(packet,IpAddress::LocalHost,4568);
        if (selector.wait()) {
            packet.clear();
            message = "";
            IpAddress address;
            unsigned short int port;
            if (selector.isReady(socketUDP) == Socket::Done) {

                if (socketUDP.receive(packet, address, port) == Socket::Done) {
                    packet>>message;
                    cout<<"Received from server (UDP) : "<<message<<endl;
                }
            }
        }
        sleep(seconds(1.f));
    }
    return 0;
}
 

Le client ne reçois rien du tout chez moi.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème avec les sélectors.
« Réponse #25 le: Juin 20, 2013, 08:45:46 am »
Extra.

Avec un code aussi minimal je peux voir l'erreur sans même tester le code :

if (selector.isReady(socketUDP) == Socket::Done)

Tu t'es un peu emmêlé les pinceaux ;)

Tu devrais utiliser ton debugger dans ce genre de situation. Avec une exécution pas à pas tu aurais vu que ça bloquait sur cette ligne, et en regardant le retour de isReady tu aurais forcément compris que ce n'était pas Socket::Done.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Problème avec les sélectors.
« Réponse #26 le: Juin 20, 2013, 08:52:40 am »
Ha en effet je ne sais pas pourquoi j'ai rajouté le == Socket::Done
Bref le bug du coup ne viens pas de la je vais devoir chercher ailleurs.

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Problème avec les sélectors.
« Réponse #27 le: Juin 20, 2013, 09:34:30 am »
Trouvé!   :D

En fait dans mon plus gros projet j'avais bien fait, j'avais pas rajouté le == Socket::Done après le isReady.

J'avais juste oublié de faire un packet.clear(); ici : (Chose que j'oublie souvent de faire vu que les fonctions send et receive des socket n'écrasent pas les données automatiquement les anciennes données lue ou écrite dans le paquet.)

while (running) {
        if (selector.wait()) {
            if (selector.isReady(clientTCP)) {
                packet.clear();
                if(clientTCP.receive(packet) == Socket::Done) {
                    string message;
                    packet>>message;
                    Network::addResponse(message);
                }
            }
            if (selector.isReady(clientUDP)) {
                packet.clear();
                if (clientUDP.receive(packet, address, port) == Socket::Done) {

                    if (address == Configuration::serverAddress) {
                        string message;
                        packet>>message;
                        Network::addResponse(message);
                        remotePortUDP = (remotePortUDP != port) ? port : remotePortUDP;
                    } else {
                        cout<<"This message don't provide from the server."<<endl;
                    }
                }
            }
        }
    }
 

J'avais oublié de faire un packet.clear() avant le clientUDP.receive(packet, address, port);
 et c'est ça qui faisait tout foiré. :/

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Problème avec les sélectors.
« Réponse #28 le: Juin 20, 2013, 10:14:21 am »
Par contre je ne vais pas dire qu'il n'y a de bugs dans mon code parce que ce n'est pas vrai..., par moment j'ai des erreurs renvoyée par la fonction send, mais, j'ai encore trop peu d'informations et encore fait trop peu de test pour savoir pourquoi ça bug...

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : Problème avec les sélectors.
« Réponse #29 le: Juin 20, 2013, 04:31:06 pm »
Bon, c'est difficile de faire un code minimiste sur ça car c'est aléatoire, mais, quand je reçois pas de données en UDP (ce qui peut arriver en UDP.) ça freeze et je suis obligé de fermé et réouvrir le programme.