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

Auteur Sujet: UDP socket ne reçoit pas les packets  (Lu 3068 fois)

0 Membres et 1 Invité sur ce sujet

HoekWax

  • Newbie
  • *
  • Messages: 4
    • Voir le profil
    • E-mail
UDP socket ne reçoit pas les packets
« le: Juillet 02, 2015, 06:38:59 pm »
Bonsoir,

Je code actuellement un chat en utilisant les sockets UDP de la SFML 2.3 (j'utilise l'UDP pour m'entrainer, pour pouvoir faire des jeux en multi en UDP).

Le problème que j'ai est que quand je lance mon programme, il marche très bien en réseau local, je lance le serveur, j'ajoute un client, le serveur le remarque, je peux ajouter plusieurs autres clients, envoyer des messages etc...

Mais quand j'essaye mon programme avec mon adresse ip publique, le serveur ne reçoit pas les informations des clients.

J'ai essayé le programme avec mon ip publique sans que le port du serveur ou celui du client ne soient redirigés, ça de ne marche pas, j'ai essayé avec les 2 ports redirigés et avec un des deux redirigés, ça ne marche pas non plus.

Voici mon code coté serveur :

std::map<unsigned short, sf::IpAddress> computerID;
 
int         get_new_client(sf::UdpSocket *socket, sf::IpAddress clientIp, unsigned short clientPort)
{
    //J'ajoute le nouveau dans ma map qui les stock tous
    computerID[clientPort] = clientIp;
    std::cout << "Nouveau client en ligne\n";
    std::cout << "Nombre de personnes en ligne : " << computerID.size() << std::endl;
    return 0;
}
 
int         main()
{
    char who;
    std::cout << "Tapez 's' pour lancer le serveur, 'c' pour le client\n";
    std::cin >> who;
    //on lance le serveur ou le client
    if (who != 's')
    {
        client();
        return 0;
    }
    sf::UdpSocket socket;
    sf::IpAddress ip = sf::IpAddress::getPublicAddress();
    sf::IpAddress ipLocal = sf::IpAddress::getLocalAddress();
    unsigned short port;
    std::cout << "L'IP locale du serveur est : " << ipLocal << std::endl;
    std::cout << "L'IP publique du serveur est : " << ip << std::endl;
    //std::cout << "Connect server to port : ";
    //std::cin >> port;
    //J'initialise le port à 2000 avec un variable globale, servPort vaut 2000
    //pour changer la valeur dans tous le code directement
    port = servPort;
    socket.bind(port);
    bool done = false;
    while (!done)
    {
        //boucle qui reçoit puis envoie le message à tous les autres pc stockés
        sf::Packet packet;
        sf::IpAddress tempIp;
        unsigned short tempPort;
        std::string str;
        std::string name;
        std::cout << "server ip : " << ip << " server port : " << port << std::endl;
        std::map<unsigned short, sf::IpAddress>::iterator tempIterator;
        std::cout << "je vais recevoir\n";
        socket.receive(packet, tempIp, tempPort);
        packet >> str >> name;
        //si un client se connecte il evoie "je me connecte tmtc" donc on ajoute le pc à la map
        if (std::strcmp(str.c_str(), "je me connecte tmtc") == 0)
        {
            get_new_client(&socket, tempIp, tempPort);
        }
        else
        {
            std::cout << name << " dit : " << str << std::endl;
            for (tempIterator = computerID.begin(); tempIterator != computerID.end(); tempIterator++)
            if (tempPort != tempIterator->first)
                socket.send(packet, tempIterator->second, tempIterator->first);
            packet.clear();
        }
    }
    return 0;
}
 

Et coté client :

int         my_receive(sf::UdpSocket *socket, std::string myname)
{
    //Reçoit les packets et affiche
    bool done = false;
    while (!done)
    {
        std::string name;
        sf::Packet packet;
        std::string str;
        std::string receivedStr;
        sf::IpAddress tempIp;
        unsigned short tempPort;
        socket->receive(packet, tempIp, tempPort);
        if (packet >> receivedStr >> name)
        {
            std::cout << "\r" << name << " : " << receivedStr << "                     " << std::endl;
            std::cout << myname << " : ";
        }
    }
    return (0);
}
 
//unsigned short servPort = 64363;
unsigned short servPort = 2000;
 
int         client()
{
    sf::UdpSocket socket;
    sf::Packet firstPacket;
    std::string name, strIp;
    unsigned short port = 0;
    unsigned short serverPort = servPort;
    std::cout << "Entrez l'IP du serveur : ";
    //J'entre l'ip (en dur pour l'instant pour aller plus vite)
    //std::cin >> strIp;
    strIp = "22.177.128.143"; //Ce n'est pas mon ip, c'est une ip d'exemple
    sf::IpAddress serverIP(strIp);
    std::cout << "Entrez le port auquel vous voulez vous connecter : ";
    std::cin >> port;
    //je choisis le port
    socket.bind(port);
    std::cout << "Choisissez un nom : ";
    std::cin >> name;
    std::string str = "je me connecte tmtc";
    firstPacket << str << "test";
    //j'affiche l'ip et le port pour verifier que c'est bon, ça l'est tjrs
    std::cout << "server ip : " << serverIP << " server port : " << serverPort << std::endl;
    //j'envoie un premier packet pour sauvegarder coté serveur le port et l'ip de ce client
    socket.send(firstPacket, serverIP, serverPort);
    bool done = false;
    //dans le while j'envoie des packet (message et nom) et je reçoi en meme temps grace au thread
    sf::Thread thread(std::bind(&my_receive, &socket, name));
    thread.launch();
    while (!done)
    {
        sf::Packet packet;
        std::string str;
        std::string receivedStr;
        sf::IpAddress tempIp;
        unsigned short tempPort;
        std::cout << "\r" << name << " : ";
        std::getline(std::cin, str);
        if (str.length() > 0)
        {
            std::cout << "je suis client et je tente d'envoyer\n";
            packet << str << name;
            socket.send(packet, serverIP, serverPort);
            std::cout << "je suis client et j'ai envoye\n";
            packet.clear();
        }
    }
    return 0;
}
 

Si vous avez un idée d'où ça peut venir...

PS : J'avais fait un programme qui utilisait le TCP qui lui marchait très bien avec mon ip publique ou locale.
« Modifié: Juillet 02, 2015, 06:42:26 pm par HoekWax »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : UDP socket ne reçoit pas les packets
« Réponse #1 le: Juillet 02, 2015, 06:45:00 pm »
Si ça marche en local c'est que ta redirection est foireuse. Re-vérifie de ce côté là, notamment que tu as bien redirigé le port correspondant pour l'UDP et pas pour TCP.
Laurent Gomila - SFML developer

HoekWax

  • Newbie
  • *
  • Messages: 4
    • Voir le profil
    • E-mail
Re : UDP socket ne reçoit pas les packets
« Réponse #2 le: Juillet 02, 2015, 07:13:40 pm »
Merci de ta réponse, effectivement ma redirections était foireuse, elle était bien en UDP mais sur le mauvais PC du réseau. J'ai refais les redirections et je viens de télécharger un logiciel pour les tester en UDP, la redirection est bonne cette fois. Mon programme marche un peu mieux mais totalement, je n'arrive à recevoir qu'un seul packet,  celui qui affiche qu'un client se connecte puis le serveur rebloque au receive et quand j'envoie du texte à partir du client le serveur de réagit pas. De plus j'ai une question, seul le port du serveur doit être redirigé en ou celui du serveur et du client ? (j'ai fais mes tests dans les 2 situations le résultat est le même)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : UDP socket ne reçoit pas les packets
« Réponse #3 le: Juillet 03, 2015, 09:23:47 am »
Tous les ports qui reçoivent doivent être redirigés localement. Sinon le routeur ne peut pas savoir à quel PC du réseau local sont destinées les données qui arrivent sur le port.
Laurent Gomila - SFML developer

HoekWax

  • Newbie
  • *
  • Messages: 4
    • Voir le profil
    • E-mail
Re : UDP socket ne reçoit pas les packets
« Réponse #4 le: Juillet 03, 2015, 03:31:29 pm »
Merci pour cette précision, par contre j'ai toujours le problème d'un seul packet reçu. Je poste le lien d'une image pour montrer le problème.

http://gyazo.com/1e8077b2ad2cc561ca388f45be206470

La situation : Je lance le serveur en haut, sur le port 4000, ouvert. Je connecte le client au serveur et lui attribue le port 4001 ouvert lui aussi. Lorsque les informations nécessaires pour le client sont remplie un packet est envoyé au serveur qui affiche qu'il y a un nouveau client, ce qui marche donc le packet est reçu mais lorsque je commence à envoyer des message le serveur bloque sur la fonction receive.

HoekWax

  • Newbie
  • *
  • Messages: 4
    • Voir le profil
    • E-mail
Re : UDP socket ne reçoit pas les packets
« Réponse #5 le: Juillet 03, 2015, 04:58:37 pm »
C'est bon ça marche ! J'ai envoyé mon chat à un ami qui a host le serveur, j'me suis connecté à son serveur et ça a marché. En fait quand j'ai testé sur mon pc, j'ai essayé d'envoyer les packets à partir du client avec l'ip publique en me disant que si ça marchait avec mon ip publique ça marcherait pour tout le monde. En fait il faut que j'utilise mon ip locale quand j'host le serveur et un client sur mon pc et que les personne en ligne utilisent la publique.
En tout cas merci pour votre aide !