IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Socket UDP ouverture automatique port client


Sujet :

C++

  1. #1
    Membre émérite Avatar de onilink_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    600
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 600
    Points : 2 453
    Points
    2 453
    Par défaut Socket UDP ouverture automatique port client
    Bonjour,
    je travaille sur le multijoueur d'un jeu, mais je gère le réseau avec des sockets UDP.
    Je cherche un moyen pour que le client n'ai pas a ouvrir de port manuellement, comme quand on utilise un socket TCP.

    Ma première question est donc: est-il possible de faire cela juste avec une socket UDP?
    J'ai tenté d'utiliser un port automatiquement délivré par l'OS (en donnant 0 a socket.bind) mais cela ne fonctionne pas:
    Client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    void runClient()
    {
        printf("Run client...\n");
     
        od::SocketUdp socket;
        if(socket.bind(0) != socket.Done)
        {
            exit(2);
        }
        printf(">%u\n", socket.getLocalPort());
     
        // 1. Send message to server
        od::StreamData packet;
        packet << std::string("Hello World");
        if(socket.send(packet, SERVER_IP, SERVER_PORT) != socket.Done)
        {
            exit(1);
        }
     
        // 2. Get response
        while(true)
        {
            printf("Waiting for response...\n");
     
            od::IPAddress remote_address;
            unsigned short remote_port;
            od::StreamData packet;
     
            if(socket.receive(packet, remote_address, remote_port) == socket.Done)
            {
                std::string str;
                packet >> str;
                printf("[%s:%u] %s\n", remote_address.toString().c_str(), remote_port, str.c_str());
            }
        }
    }
    Server
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    void runServer()
    {
        printf("Run server...\n");
     
        od::SocketUdp socket_send;
        od::SocketUdp socket_receive;
        if(socket_receive.bind(7777) != socket_receive.Done)
        {
            exit(1);
        }
     
        while(true)
        {
            printf("Waiting for message...\n");
     
            od::IPAddress remote_address;
            unsigned short remote_port;
            od::StreamData packet;
     
            if(socket_receive.receive(packet, remote_address, remote_port) == socket_receive.Done)
            {
                std::string str;
                packet >> str;
                printf("[%s:%u] %s\n", remote_address.toString().c_str(), remote_port, str.c_str());
                printf("Send response\n");
     
                od::StreamData packet;
                packet << std::string("Hello World");
                socket_send.send(packet, remote_address, remote_port);
            }
            else
                break;
        }
    }
    En local ce code fonctionne parfaitement et donne:
    Client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Run client...
    >1369
    Waiting for response...
    [192.168.0.12:1370] Hello World
    Waiting for response...
    Server
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Run server...
    Waiting for message...
    [192.168.0.12:1369] Hello World
    Send response
    En online le serveur reçoit bien le message, mais quand il répond au client, le client ne reçoit jamais de réponse.

    Est ce que je me suis trompé ou/et mal compris quelque chose, ou est ce impossible de cette manière?

    Si cela n'est pas possible en tant que tel, comment est-ce que je dois procéder?

    Merci d'avance.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Salut,
    recherche les termes de nat traversal, hole punching et server relay.
    Initialiser avec le port 0 laisse juste le choix du port à la discrétion du pc et ne change rien.

  3. #3
    Membre émérite Avatar de onilink_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    600
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 600
    Points : 2 453
    Points
    2 453
    Par défaut
    Merci pour les pistes, j'ai regardé du côté du hole punching du coup et j'ai trouvé un post très interessant (en anglais) ici: https://steamcommunity.com/app/42752...9771755670102/
    Par contre c'est assez magique comme technique Je suis pas sur de comprendre ce qui fait que ça fonctionne.
    Bref je testerais d'ici peu et je vous tiens au courant.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    En gros la théorie est que quand tu envoies des données, tu crées un mapping entre ton port externe et ton port interne qui est valable un certain temps pour pouvoir recevoir une réponse. Et en maintenant un débit entre les parties, ce chemin est maintenu et utilisable.

  5. #5
    Membre émérite Avatar de onilink_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    600
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 600
    Points : 2 453
    Points
    2 453
    Par défaut
    Merci pour les précisions :p
    Finalement après avoir regardé un peu les solutions simples/rapides que j'avais sous la main, j'ai opté pour la bibliothèque ENet : http://enet.bespin.org/index.html
    Ils ne mentionnent nulle part dans la doc/features l'utilisation d'hole punching, mais c'est une lib réseau UDP et tout marche sans soucis et sans avoir a faire de bidouilles côté client.
    Donc je suppose qu'en interne ils doivent utiliser quelque chose de similaire.
    Du coup je suis parti sur ça et j'ai porté ce que j'avais fait avec, et tout marche très bien.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [UDP] Serveur fixe port client
    Par sone47 dans le forum Réseau
    Réponses: 4
    Dernier message: 12/01/2012, 09h30
  2. Socket UDP: écoute sur un seul port?
    Par toninlg dans le forum C#
    Réponses: 3
    Dernier message: 04/12/2007, 08h12
  3. [VB.NET 2.0] [Socket] Tester ouverture de ports !
    Par Aspic dans le forum VB.NET
    Réponses: 1
    Dernier message: 26/05/2007, 17h11
  4. [Socket] Reconnexion automatique du client
    Par sorry60 dans le forum Réseau
    Réponses: 10
    Dernier message: 09/01/2007, 20h24
  5. [sockets][UDP][C/C++] serveur multi-clients
    Par l@rry dans le forum Développement
    Réponses: 4
    Dernier message: 08/06/2006, 14h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo