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

Qt Discussion :

Communication UDP sans ouverture de port


Sujet :

Qt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 45
    Par défaut Communication UDP sans ouverture de port
    Bonjour

    Je suis entrain de faire une application client/serveur communicant par UDP.
    Actuellement les clients doivent ouvrir le port 3301 sur leur routeur pour que les sockets transite correctement (et le serveur doit ouvrir le port 3300, mais sur le serveur ça ne me dérange pas).
    Je voudrais savoir s'il est possible de recevoir les sockets UDP sur le client sans qu'il ouvre de port ??

    Je post un peu de code quand même. Je travail avec Qt, ça fonctionne, mais sans l'ouverture de port les sockets sont bloqué par le routeur du client :
    Coté Serveur :
    -Ecoute
    Code : C++
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    m_udpSocket = new QUdpSocket;
    m_udpSocket->bind(QHostAddress::Any, 3300, QUdpSocket::ShareAddress);
    connect(m_udpSocket, SIGNAL(readyRead()), this, SLOT(get()));
    -Envoie
    Code : C++
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    QUdpSocket udpSocket;
    udpSocket.bind(3301); // Je ne sais pas si c'est important de faire ça, mais ça définit le port source du socket
    udpSocket.writeDatagram(datagram, ip, 3301);

    Coté Client :
    -Ecoute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    m_serverAdress = new QHostAddress("**.**.***.**");
     
    m_udpSocket = new QUdpSocket;
    m_udpSocket->bind(QHostAddress::Any, 3301, QUdpSocket::ShareAddress); // Si je mets *m_serverAdress au lieu de QHostAddress::Any, Je ne reçoit plus rien sur le client même si le port est ouvert
    connect(m_udpSocket, SIGNAL(readyRead()), this, SLOT(get()));
    -Envoie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_udpSocket->writeDatagram(datagram, *m_serverAdress, 3300);

  2. #2
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Citation Envoyé par Thixomag Voir le message
    Je voudrais savoir s'il est possible de recevoir les sockets UDP sur le client sans qu'il ouvre de port ??
    Oui c'est possible, mais ça dépend hautement du matériel (le modem/routeur/point d'accdès wifi) que ton client aura. Donc il n'y a pas de réponse simple, ça marchera avec certains clients et pas avec d'autres.

    La seule solution technique à adopter pour être certain(*) qu'un client pourra être contacté par un serveur est:

    - d'utiliser uniquement le protocole TCP et pas UDP

    - que ce soit le client qui initie la connexion vers le serveur et pas l'inverse.

    Toutes les autres solutions qui ne respectent pas les deux contraintes ci-dessus ne pourront te garantir que ça marchera chez tout le monde sans qu'ils aient à ouvrir un port à la main.

    Tu peux également imaginer une solution hybride: essayer d'initier une connexion en UDP et si le logiciel se rend compte que ça ne passe pas, il utilise automatiquement TCP en remplacement. Skype par exemple utilise ce genre de technique.

    Mais avant tout, cela dépend de tes besoins spécifiques à ton projet (que tu pourras peut-être nous détailler). Par exemple on a souvent tendance à imaginer à priori que l'UDP est indispensable pour notre projet alors que ce n'est pas toujours le cas. Par exemple j'ai appris récemment que World of Warcraft n'utilisait que le protocole TCP. Comme quoi...

    (*) Je parle ici des abonnements au net classiques pour les particuliers. Evidemment, ça ne s'applique pas aux accès internet fourni par les administrations, écoles, entreprises, ... qui elles peuvent définir des restrictions beaucoup plus contraignantes pour assurer la sécurité de leur réseau et limiter son usage.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 45
    Par défaut
    Mon projet nécessite obligatoirement de l'UDP, puis que c'est un FPS.

    Citation Envoyé par nouknouk Voir le message
    Oui c'est possible, mais ça dépend hautement du matériel (le modem/routeur/point d'accdès wifi) que ton client aura. Donc il n'y a pas de réponse simple, ça marchera avec certains clients et pas avec d'autres.
    Voila la réponse que j'attendais. J'aimerais en savoir plus, quel sont les routeurs avec les quels ça fonctionne ? Et côté code, que dois-je faire pour que les sockets passent chez le client?

    Le cas de skype est justement intéressant, car chez moi et chez mes co-développeurs les sockets de skype passe en UDP (on utilise wireshark pour sniffer).
    Donc je devrais pouvoir faire un truc qui marche sans ouverture de port fonctionnant entre mes co-développeurs, que dois-je faire ?

    Merci beaucoup de m'aider !

  4. #4
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Citation Envoyé par Thixomag Voir le message
    Mon projet nécessite obligatoirement de l'UDP, puis que c'est un FPS.
    Effectivement.

    Voila la réponse que j'attendais. J'aimerais en savoir plus, quel sont les routeurs avec les quels ça fonctionne ? Et côté code, que dois-je faire pour que les sockets passent chez le client?
    Malheureusement, les constructeurs de matériel n'informent que très peu sur ce point technique précis. Donc la seule solution semble de faire des tests pour chaque matériel.

    Avec une freebox (v5) je peux tout à fait jouer à Counter Strike Source (qui utilise UDP) sans rien avoir à configurer.
    Ce n'était pas le cas il y a quelques années quand j'avais un modem WiFi Wanadoo où la configuration de redirection de port était obligatoire.

    Le cas de skype est justement intéressant, car chez moi et chez mes co-développeurs les sockets de skype passe en UDP (on utilise wireshark pour sniffer).
    Certains NAT sont capable de laisser passer les flux entrant UDP si des paquets ont été préalablement émis par le client vers le même serveur (autrement dit, il est indispensable que le client commence par envoyer des paquets UDP vers le serveur avant que ce dernier ne puisse lui en envoyer).

    Par exemple:

    - au temps T, le client A envoie un paquet UDP vers le serveur publique 123.234.123.234 sur le port 1234. Le paquet passera donc par son NAT qui en gardera une trace (client A a émis un paquet vers 123.234.123.234 port 1234).

    - si au temps T+x le NAT reçoit un paquet venant de 123.234.123.234 sur le port 1234, il estime alors probable que ce dernier soit destiné à l'ordinateur A, étant donné que ce dernier a émis sur le même port et vers le même serveur il y a peu. Le paquet est donc routé vers la client A.

    De plus, il est évident que ce genre de système montre rapidement ses limites. Par exemple, cette technique ne fonctionnera plus si deux clients sur le même NAT (A et B) veulent jouer en même temps à ton FPS.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 45
    Par défaut
    J'ai réussit !!

    Voila le code que j'utilise en se moment :
    Coté Client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //Ecoute
        m_udpSocket = new QUdpSocket;
        m_udpSocket->bind(QHostAddress::Any, m_port, QUdpSocket::ShareAddress);
        connect(m_udpSocket, SIGNAL(readyRead()), this, SLOT(get()));
     
    // ...
     
    //Envoi
        m_udpSocket->writeDatagram(datagram, *m_adresseServeur, m_port);
    Coté Serveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //Ecoute
        m_udpSocket = new QUdpSocket;
        m_udpSocket->bind(QHostAddress::Any, m_port, QUdpSocket::ShareAddress);
        connect(m_udpSocket, SIGNAL(readyRead()), this, SLOT(get()));
     
    // ...
     
    //Envoi
        m_udpSocket->writeDatagram(datagram, ipCLient, m_port);
    Les deux parties sont exactement pareil niveau code.
    Mais côté serveur j'ouvre le port, côté client je touche à rien. Ensuite c'est le client qui doit envoyer le premier paquet.

    Pourquoi au début ça ne marchait pas, parce que j'utilisai deux ports diffèrents et deux sockets diffèrents pour l'envoi et la réception.
    Il faut utiliser le même port et le même socket pour l'envoi, comme ça le port source est définit :

    Client->Serveur 3300->3300 (port source->port cible du paquet)
    Serveur écoute sur 3300
    Serveur->Client 3300->3300 (port source->port cible du paquet)
    Client écoute sur 3300

Discussions similaires

  1. Libérer le port en cours d'une communication UDP
    Par wagui26 dans le forum Débuter avec Java
    Réponses: 9
    Dernier message: 10/12/2008, 11h40
  2. problème ouverture de port série
    Par philippe13 dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 26/04/2006, 16h42
  3. Communication Kit Velleman K8063 par port série et TComport
    Par carotreger dans le forum Composants VCL
    Réponses: 16
    Dernier message: 07/11/2005, 21h11
  4. Ouverture de port 1433
    Par dimdidi dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 12/07/2005, 14h49
  5. limiter l'ouverture des ports internets
    Par Paradam dans le forum Développement
    Réponses: 2
    Dernier message: 16/06/2003, 16h03

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