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

Auteur Sujet: Problème avec SocketSelector  (Lu 1149 fois)

0 Membres et 1 Invité sur ce sujet

Paul-Darius

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
    • E-mail
Problème avec SocketSelector
« le: Novembre 26, 2014, 09:31:27 pm »
Bonsoir à tous,
Cela fait déjà quelques temps que je m'intéresse à la librairie SFML et j'ai attaqué il y a quelques jours la partie "réseaux" de cette dernière.

J'ai repris le code typique présenté dans la page de documentation concernant SocketSelector. Il se trouve que j'ai quelques difficultés à en comprendre les mécanismes et c'est pourquoi j'ai cherché à modifier ce code de base pour lui faire faire ce que je veux. Mais j'éprouve quelques difficultés. C'est la raison pour laquelle ce code est rempli de "printf" indiquant où en est le programme lorsque je l'éxécute.

Concrètement ce que je cherche à faire dans ce code c'est :
- connecter N clients à un serveur (ça j'y arrive)
- faire en sorte que chaque fois qu'un nouveau client se connecte tous les autres utilisateurs soient prévenus. (ça ça marche aussi)
- faire en sorte que chaque fois qu'un message est envoyé le serveur l'affiche dans sa console (puis à l'avenir qu'il le renvoie vers tous les clients afin de faire un mini-chat).

Et c'est ce dernier point qui me bloque.
Le scénario est le suivant :
-Je connecte un premier client à mon serveur. Les printf que j'utilisent m'indiquent que la connexion s'est bien produite. J'ai pu découvrir à ce propos que le client envoie deux messages suite à cette connexion. Je soupçonne qu'il s'agisse là d'accusés de réception : Client1 -> Serveur dit : "ok je me suis connecté" puis Client1 -> Serveur dit : "j'ai bien reçu ta chaîne de caractère indiquant qu'un nouveau client s'était connecté" (à savoir le client1 lui-même).
-J'envoie un message au serveur depuis mon client 1. Rien ne semble se produire.
-Je connecte un second client à mon serveur. Tout se passe bien. Et une fois ceci fait le message précédemment envoyé s'affiche.

1) J'ai beau chercher, je ne comprends pas du tout pourquoi le message émis par le client 1 ne s'affiche dans la console du serveur qu'après que le client 2 se soit connecté. Est-ce qu'une personne bien informée pourrait m'en expliquer la raison ?

2) Par ailleurs j'ai constaté que lorsque je quittais inopinément un programme client ( CTRL+C sous unix ) une boucle infinie se lançait dans le serveur. Je suppose que le serveur n'a pas été programmé pour prévoir un cas de déconnexion. Mais je ne comprends pas ce qui le fait entrer dans cette boucle et je ne sais pas comment résoudre ce problème. Pourriez-vous m'aider sur ce point également ?

Le code, qui est une simple adaptation de celui de la page sur SocketSelector est recopié ici :

#include <iostream>
#include <SFML/Network.hpp>
#include <list>

int main()
{
    // Create a socket to listen to new connections
    sf::TcpListener listener;
    listener.listen(5000);
    // Create a list to store the future clients
    std::list<sf::TcpSocket*> clients;
    // Create a selector
    sf::SocketSelector selector;
    // Add the listener to the selector
    selector.add(listener);
    // Endless loop that waits for new connections
    while (true)
    {
        // Make the selector wait for data on any socket
        if (selector.wait())
        {
            // Test the listener
            if (selector.isReady(listener))
            {
                // The listener is ready: there is a pending connection
                sf::TcpSocket* client = new sf::TcpSocket;
                if (listener.accept(*client) == sf::Socket::Done)
                {
                    // Add the new client to the clients list
                    clients.push_back(client);
                    // Add the new client to the selector so that we will
                    // be notified when he sends something
                    selector.add(*client);
                    sf::Packet packet;
                    std::string str = "Serveur : Un nouveau client s'est connecté.\n";
                    printf("%s",str.c_str());
                    packet << str;
                    int i=0;
                    for (std::list<sf::TcpSocket*>::iterator it = clients.begin(); it != clients.end(); ++it)
                    {
                        sf::TcpSocket& client = **it;
                        if (!(client.send(packet) == sf::Socket::Done))
                        {
                            printf("Le paquet contenant \"un nouveau client vient de se connecter n'a pas pu être envoyé au client %d\n\"",i);
                        }
                        else printf("Le paquet contenant l'info de nouvelle connexion a bel et bien été envoyé au client %d.\n");
                        i++;
                    }
                   
                }
                else
                {
                    printf("La connexion n'a pas pu être établie.\n");
                    // Error, we won't get a new connection, delete the socket
                    delete client;
                }
            }
            else
            {
                // The listener socket is not ready, test all other sockets (the clients)
                printf("On a reçu des données d'autre chose qu'en provenance du listeneur.\n");
                int j = 0;
                for (std::list<sf::TcpSocket*>::iterator it = clients.begin(); it != clients.end(); ++it)
                {
                    sf::TcpSocket& client = **it;
                    if (selector.isReady(client))
                    {
                        printf("On a reçu des paquets venant du client %d\n", j);
                        // The client has sent some data, we can receive it
                        sf::Packet packet;
                        if (client.receive(packet) == sf::Socket::Done)
                        {
                            std::string msg;
                            packet >> msg;
                            std::cout << msg;
                           
                        }
                    }
                    j++;
                }
            }
        }
    }
}

Je vous remercie chaleureusement pour votre aide.

Paul-Darius

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
    • E-mail
Re : Problème avec SocketSelector
« Réponse #1 le: Décembre 04, 2014, 07:01:12 pm »
J'ai obtenu la réponse à ma question sur un doublon posté ici :http://openclassrooms.com/forum/sujet/sfml-petite-incomprehension-avec-socketselector

 

anything