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

Auteur Sujet: [SFML2] Organisation / logique et erreur  (Lu 2498 fois)

0 Membres et 1 Invité sur ce sujet

Archimed78

  • Newbie
  • *
  • Messages: 35
    • Voir le profil
[SFML2] Organisation / logique et erreur
« le: Juillet 10, 2012, 03:24:22 pm »
Bonjour a tous,

J'ai un soucis de logique et d'organisation de mon code.
Il est difficile d'expliqué le problème, je vais donc vous montrer le code et expliqué mon soucis par la suite.

Il s'agit d'un simple serveur/client standard. Hors pour un certaine organisation du code j'ai décidé de mettre un Thread par écoute client. On retrouve donc deux classe : Gestionnaire et Client.

La classe Gestionnaire qui gèrent tout les clients et la classe Client gére le Thread d’écoute.

Gestionnaire.cpp
#include "Gestionnaire.h"

Gestionnaire::Gestionnaire()
{
    std::cout << "Instance Gestionnaire - OK" << std::endl;
    sf::TcpListener ecoute;
    ecoute.listen(PORT_ECOUTE);
    std::cout << "Lancement ecoute : port " << PORT_ECOUTE << std::endl;
    while (true)
    {
        sf::TcpSocket *client = new sf::TcpSocket();
        std::cout << "Attente de connexion " << std::endl;
        if (ecoute.accept(*client) == sf::Socket::Done)
        {
            std::cout << "Tentative connexion (" << client->getRemoteAddress() << ")" << std::endl;
            m_mutexGlobale.lock();
            m_listeClients.push_back(new Client(this, client));
            m_mutexGlobale.unlock();
            std::cout << "Connexion de " << client->getRemoteAddress() << "- OK" << std::endl;
        }
    }
}

Gestionnaire::~Gestionnaire()
{
    for (unsigned int i = 0; i < m_listeClients.size(); i++)
    {
        std::cout << "Liberation Client (" << m_listeClients[i] << ")" << std::endl;
        delete m_listeClients[i];
    }
    std::cout << "Liberation Gestionnaire - OK" << std::endl;
}
 

Client.cpp
Client::Client(Gestionnaire *gestionnaire, sf::TcpSocket *socket)
{
    m_gestionnaire = gestionnaire;
    m_socket = socket;
    m_threadEnCour = true;
    m_threadSocket = new sf::Thread(&Client::debuterEcoute, this);
    std::cout << "Instance Client - OK" << std::endl;
    m_threadSocket->launch();
}

Client::~Client()
{
    delete m_threadSocket;
    delete m_socket;
}

void Client::debuterEcoute()
{
    std::cout << "Lancement d\'ecoute (" << m_socket->getRemoteAddress() << ")" << std::endl;
    while (m_threadEnCour)
    {
        sf::Packet packetReception;
        sf::TcpSocket::Status status = m_socket->receive(packetReception);

        if (status == sf::TcpSocket::Disconnected)
        {
            m_threadEnCour = false;
            std::cout << "Deconnexion Client (" << m_socket->getRemoteAddress() << ")" << std::endl;
        }
        else if (status == sf::TcpSocket::Error)
        {
            m_threadEnCour = false;
            std::cout << "Erreur : Paquet erreur (" << m_socket->getRemoteAddress() << ")" << std::endl;
        }
        else if (status == sf::TcpSocket::Done)
        {
            std::cout << "Reception paquet - OK (" << m_socket->getRemoteAddress() << ")" << std::endl;
        }
    }
    std::cout << "Fin d\'ecoute (" << m_socket->getRemoteAddress() << ")" << std::endl;

    // ici, code susceptible de devoir désalloué la classe client et supprimer le pointeur dans la classe Gestionnaire.

}
 

Mon soucis est le suivant : je souhaite que lorsque mon Thread soit terminé, donc en gros que le client c'est déconnecté ou qu'il y a eu une erreur, que le Thread demande a la classe Gestionnaire de non seulement désalloué la mémoire de l'instance de Client mais aussi de supprimer le pointeur dans le vector.

Hors problème, car si a la fin de mon Thread je demande a la classe Gestionnaire de supprimer Client (du style m_gestionnaire->supprClient(this); ), étant donné que c'est le Thread qui la appelé, le Thread sera donc toujours en fonction et donc provoque une erreur lors de sa destruction.

J’espère avoir été le plus claire possible, ma question est donc la suivante : peut-on demander a un Thread de d'auto détruire la classe qui le contient, si oui comment ?

En cas de question ou de non compréhension j'essayerai de mieux reformulé

Merci beaucoup de votre aide.
« Modifié: Juillet 10, 2012, 07:10:37 pm par Archimed78 »

Archimed78

  • Newbie
  • *
  • Messages: 35
    • Voir le profil
Re : [SFML2] Organisation / logique et erreur
« Réponse #1 le: Juillet 12, 2012, 02:01:19 pm »
Au vue des réponses que j'ai eu, j'ai du très mal m'exprimer. Alors je vais posé une question simple qui serai susceptible que j'avance tout de même  :)

Comment gèrent ton les déconnexion des clients en SFML2 ?

Merci beaucoup

Canadadry

  • Hero Member
  • *****
  • Messages: 1081
    • Voir le profil
Re : [SFML2] Organisation / logique et erreur
« Réponse #2 le: Juillet 15, 2012, 11:06:37 pm »
Tu devrais utiliser un sélecteur. Regarde les exemples, c'est la meilleur façon de faire.

Archimed78

  • Newbie
  • *
  • Messages: 35
    • Voir le profil
Re : [SFML2] Organisation / logique et erreur
« Réponse #3 le: Juillet 24, 2012, 06:17:23 pm »
En faite je n'arrive pas du tout a résoudre le problème.

En ce qui concerne les sélecteurs, ce n'est pas viable dans mon cas car le traitement pour chaque clients est long, donc pendant le traitement d'un client, les autres clients ne vont pas attendre du coup.

En faite avec la SMFL 1.6 j'utilisai l'héritage sur un Thread, comme sa quand le Thread se terminais, il appelais de destructeur de la classe qu'il héritai et j'étai tranquille. Comment puis-je retrouver le même fonctionnement sans utilisé l'héritage (car j'ai vue que ce n’était plus possible avec la SFML 2.0) ?

Merci beaucoup.

Archimed78

  • Newbie
  • *
  • Messages: 35
    • Voir le profil
Re : [SFML2] Organisation / logique et erreur
« Réponse #4 le: Juillet 25, 2012, 07:30:05 pm »
En faite après avoir bien réfléchit je pense que avec les selector sa peut le faire.

Mais je me pose une question, comment fait t'on pour fermer le programme proprement (avec les delete qui vont bien) si la fonction wait est bloquante ?

Merci beaucoup

 

anything