Impossible d'envoyer une commande par UDP en dehors de son réseau local.

Le problème exposé dans ce sujet a été résolu.

Bonjour à tous et à toutes !

Je reviens vers vous après quelques jours de recherches car je suis totalement bloqué pour mon projet. :(

Je suis actuellement en train de créer deux programmes permettant de communiquer avec des objets connectés. L’un reçoit les données (et fonctionne) , l’autre doit envoyer des données (et…semi-fonctionne o_O).

Je vais essayer de vous expliquer les tests que j’ai pu faire.

Lorsque je combine les deux programmes, tout fonctionne. Par exemple, il recevait des données et tout de suite après, avec les informations du paquet reçu (IP et port), je pouvais envoyer une commande à mon objet. Mais ce n’est pas ce que je veux. Je dois avoir la possibilité d’envoyer une commande n’importe quand.

Mais lorsque je sépare les deux programmes, c’est différent… Pourtant, le code est normalement bon. C’est le même morceau, mais mis à part.

En local, mes deux programmes communiquent bien. Sur le même ordinateur, ou sur deux ordinateurs du même réseau.

Je peux aussi passer par l’adresse de ma box pour me renvoyer des messages. Au final, si je comprends bien, je reste dans une sorte de réseau local même si c’est mon IP publique…

Enfin, pour savoir si mon programme ne fonctionnait pas correctement, j’ai essayé une commande présente sur GNU/Linux : bash echo "Ma commande" > /dev/udp/123.456.789.123/1234 . Mais ça ne fonctionne pas. Pareil pour d’autre petits logiciels trouvés. J’ai même essayé d’envoyer des données à mon téléphone portable en UDP pour simuler un objet connecté, mais toujours rien.

Au résumé, de ce que j’ai pu comprendre, je peux recevoir des données de n’importe qui, peu importe son emplacement sur Terre. Mais je ne peux presque jamais leur envoyer des données (sauf dans le cas mentionné ci-dessus où je réceptionne un message, puis renvoie tout de suite une commande). D’où le "ça semi-fonctionne". :euh:

Si jamais vous avez besoin de mon code, je pourrais vous le montrer. ^^

Aussi, c’est la première fois que j’utilise "DatagramSocket" et les "DatagramPacket" ainsi que toutes les fonctionnalités concernant le réseau en Java. De plus, je ne connais peut-être pas encore assez bien l’UDP. Peut-être ai-je oublié quelque chose de simple ?

Quoi qu’il en soit, je vous remercie de m’avoir lu.

A bientôt ! :)

PS : J’ai effectué au préalable une petite redirection de port sur ma FreeBox en UDP.

+0 -0

Salut,

Si j’ai bien compris, tout fonctionne correctement en réseau local1, mais dès que tu sors du réseau, ça ne fonctionne plus ?

Ça ressemble à une problème au niveau de la configuration de ta box. Je dirai qu’il faut ajouter une règle NAT qui permettra à ta box de faire l’association entre un numéro de port entrant et une adresse IP locale.

À+


  1. À noter qu’en local, l’ip publique va d’abord te diriger vers ta box pour envoyer les paquets… Qui va détecter que tu es sur son réseau, et donc tu ne sortiras jamais. D’où le même comportement qu’en local.

Bonjour ! Et merci de ta réponse. :)

Ah ! Merci pour ton explication. C’est sympa à savoir ça.

Le numéro de port entrant serait donc celui de mon objet connecté j’imagine. C’est bien ça ? Mais si il change régulièrement, c’est possible quand même d’associer le port à une adresse IP locale ?

Ça fait longtemps que j’utilise l’interface de la FreeBox, mais je n’ai jamais vu de paramètre NAT. :(

La configuration du NAT, c’est différent de ça ? Redirection d’adresses IP

Je vais faire mes recherches à ce sujet. En attendant, je suis ouvert à toute autre réponse. :)

Et désolé pour mes questions. :honte: !

+0 -0

Pour la freebox, mode avancé :

  • Dans "Baux Statiques" tu te définis une IP statique à ton PC ;)
Baux Statiques
Baux Statiques
  • Dans "Gestion des ports" :
Gestion des ports
Gestion des ports

Vérifie le premier point, le deuxième semble OK. Tu peux aussi faire un ifconfig ou ipconfig pour vérifier ton ip dhcp.

+2 -0

Bonjour et merci pour ta réponse.

Je viens d’essayer et cela ne fonctionne pas. :'(

Je ne vois vraiment pas ce qu’il pourrait y avoir à modifier.

EDIT : En envoyant un message de mon téléphone, je me suis aperçu que l’adresse initiale ainsi que le port changeaient dans le paquet reçu. J’imagine que c’est aussi le cas pour mes objets connectés. Mais je ne sais pas si cette information est utile. :/

EDIT 2 : Rha ! Même en réutilisant cette ip changée, ça ne fonctionne pas.

+0 -0

Oui. L’adresse IP de l’ordinateur qui me sert de serveur pour mes tests est 192.168.0.18. Dans le doute j’avais fait plusieurs fois la commande à différents moments. Mais elle n’a pas changé.

AlliageSphere

Aucun pare-feu (de type iptable) d’actif ?

Regarde si tu ne peux pas ping ton port avec le protocole udp pour savoir si l’erreur vient de ton application ou de ton parefeu/routeur/pc.

Bonjour à vous tous ! Salut unidan !

Merci etherpin pour ce lien, il m’aide à mieux comprendre le fonctionnement de l’UDP. Mais par rapport à la partie "Envoi d’un message", je ne comprends pas pourquoi ça ne fonctionnerait pas chez moi.

Aujourd’hui, j’ai installé mes programmes sur une Raspberry et j’ai changé le port de mon serveur (5000) en 42645. En regardant sur internet, j’ai vu que le port 5000 était utilisé par un autre protocole il me semble. J’ai espéré que le problème venait de là, mais non.

@A-312, je ne sais pas trop comment vérifier cela, mais sur la Freebox, tout me semble correct à présent. Sur mon ordinateur, j’avais désactivé mon pare-feu et en plus rajouté des droits pour mon application.

Et sur ma Raspberry, je n’ai touché à rien.

Je n’ai pas réussi à pinger mon téléphone, ni l’objet connecté. Mais je peux tout de même pinger d’autres réseaux. Du coup, je n’ai pas réussi à pinger des ports spécifiques. D’ailleurs, je ne sais pas comment je peux faire cela.

@unidan, voilà. Je ne sais pas si toutes les informations sont ici par contre. :/ Pour ce qui est des paquets envoyés et reçus, je ne sais pas vraiment comment avoir ces informations là. J’ai entendu parler de Wireshark, mais je ne sais pas l’utiliser. Je vais voir ça. Réseau.png

Aussi, pourquoi selon vous, je suis capable d’envoyer une commande à mon objet connecté tout juste après avoir reçu un message de sa part. C’est étrange non ?

EDIT 2 : J’ai créé un petit programme Client/Serveur avec le protocole TCP et c’est le même soucis qu’en UDP.

+0 -0

Aussi, pourquoi selon vous, je suis capable d’envoyer une commande à mon objet connecté tout juste après avoir reçu un message de sa part. C’est étrange non ?

Non, ça c’est normal. Si une machine est derrière ta box et qu’elle envoie un message à l’extérieur, la box va automatiquement modifier temporairement sa configuration NAT pour laisser passer la réponse. Si elle ne le faisait pas, en fait, tu ne pourrais jamais aller sur le web depuis derrière ta box… car tu ne recevrais jamais les réponses des serveurs web que tu contactes.

Que ce soit en TCP ou en UDP, fondamentalement, le NAT fonctionne de la même façon. Si tu as une machine avec l’IP 192.168.1.1 derrière la box qui attend un paquet UDP sur le port 1234, tu dois indiquer dans la configuration de ta box que tout paquet reçu sur le port 1234 doit être renvoyé sur 192.168.1.1. Sinon on ne peut pas te contacter depuis l’extérieur. ET idéalement, le couple IP/port ne doit plus changer une fois défini.

Quand c’est toi qui est à l’initiative depuis derrière ta box c’est un peu différent. La box voit passer la requête et enregistre qu’elle devra te retransmettre la réponse.

Il me semble avoir vu passer un cours de réseau sur ZDS, tu devrais sans doute le lire ou le relire pour bien comprendre ce qu’est le NAT et ce qui se passe.

+1 -0

Aussi, pourquoi selon vous, je suis capable d’envoyer une commande à mon objet connecté tout juste après avoir reçu un message de sa part. C’est étrange non ?

Non, ça c’est normal. Si une machine est derrière ta box et qu’elle envoie un message à l’extérieur, la box va automatiquement modifier temporairement sa configuration NAT pour laisser passer la réponse. Si elle ne le faisait pas, en fait, tu ne pourrais jamais aller sur le web depuis derrière ta box… car tu ne recevrais jamais les réponses des serveurs web que tu contactes.

QuentinC

Pour pinailler, c’est pas totalement exact, le web c’est du TCP donc il y a une connexion établie de bout en bout. Ici c’est plutôt un cas de hole punching et correspond plus à la situation des jeux vidéos.

Ton objet connecté est sur quelle réseau ? est-ce qu’il ne serait pas NATé lui-aussi ? Dans ce cas-là tu auras besoin de lire les choses horribles que sont ICE, TURN et STUN, et tu auras probablement besoin de lire un bon cours de réseau comme le souligne QuentinC.

Bonjour QuentinC ! Merci pour ces précisions. De ce que j’ai pu comprendre, il y a toujours dans ce que vous dites cette même histoire de redirection de port. Pourtant je pense avoir correctement configuré les redirections, notamment avec les autres informations de @A-312.

Je vais voir sur le site si je trouve ce cours. Je pense que ça ne me fera pas de mal.

@unidan . Le hole punching serait le moyen pour moi d’arriver à communiquer avec la balise ? Pour ce genre de chose, un employé m’avait dit qu’il fallait garder un canal ouvert entre les deux appareils. Mais je n’en sais pas plus… Mais la description du lien Wikipédia semble s’y rapprocher on dirait. Je vais m’y intéresser de plus près.

L’objet dispose d’une carte SIM avec accès à internet. Mais l’appareil n’est pas connecté au réseau d’une entreprise par exemple. Mais je ne sais pas si il est "NATé" du coup. En fait, je sais très peu de choses sur l’objet en question. Je ne connais son IP et son port utilisé qu’au moment ou je reçoit une information. Donc si je ne stocke pas ces données là, je ne pourrais plus jamais communiquer avec puisque les informations pourraient très bien changer.

Ah ! Mince ! ICE, TURN et STUN son si horribles que ça ? :lol:

Bon, il faudra aussi que j’essaye de comprendre à quoi servent ces choses. ^^

+0 -0

Je ne suis pas sûr d’avoir compris ce que tu viens de dire. :honte:

EDIT : Je viens de regarder cette vidéo : https://www.youtube.com/watch?v=s_-UCmuiYW8. C’est ce que tu expliques il me semble, non ? Donc si je comprends bien, je dois pinger par avance l’appareil que je veux, puis ensuite, je lui envoie des données.

Ce serait aussi simple que ça ? Faire un simple ping sur l’adresse IP de l’objet au préalable ?

+0 -0

Je ne suis pas sûr d’avoir compris ce que tu viens de dire. :honte:

EDIT : Je viens de regarder cette vidéo : https://www.youtube.com/watch?v=s_-UCmuiYW8. C’est ce que tu expliques il me semble, non ? Donc si je comprends bien, je dois pinger par avance l’appareil que je veux, puis ensuite, je lui envoie des données.

Ce serait aussi simple que ça ?

AlliageSphere

Si c’est ton appareil qui est derrière un NAT sans redirection de port, c’est l’inverse que tu dois faire. Ton appareil ping ton serveur accessible, puis ton serveur peut communiquer avec lui. Mais l’appareil doit régulièrement envoyer des paquets pour garder le trou à travers le NAT, donc il te faut une sorte de mécanisme de ping si tu dois communiquer plus tard.

+1 -0

Ah ! Dans ce sens là ? Ok. ^^

Mon appareil envoie des données obligatoirement toutes les deux minutes pour dire "Hey ! Je suis en vie !". 2 minutes, c’est trop long j’imagine pour ce mécanisme. Non ? Sachant que je ne peux pas lui dire de faire moins… :(

+0 -0

Effectivement, pour maintenir le trou PAT ouvert, il faut faire des échanges régulièrement. Je ne connais pas la temporisation des Free Box. Sinon,on peut faire un ping puis utiliser UDP quand on veut communiquer.

+1 -0

D’accord d’accord. Je crois que je commence à comprendre ce qu’il faut faire. Apparemment, le Java n’est pas capable de faire pinger correctement un appareil. Donc je vais voir si en exécutant une commande sur GNU/Linux depuis le Java, ça pourrait fonctionner.

Aussi, quand vous parlez de pinger, c’est pinger une IP ou une IP ET un port ?

Je viens d’essayer de pinger mon portable et une balise et tous les paquets se perdent. Mes appareils ne semblent pas disponibles. Si ça, ça ne fonctionne pas, l’envoi d’une commande risque d’être compliqué du coup. :/

EDIT : Après, j’ai une alternative. C’est pas génial, mais bon. Si je peux envoyer une commande directement après avoir reçu une réponse, je pourrais très bien envoyer les commandes dans un tableau. Une sorte de liste d’attente. Et dès qu’un objet me parle, je lui envoie tout de suite toutes les commandes qui lui sont associées. L’inconvénient, c’est que si elle ne répond que toutes les heures, la commande ne sera effectuée que l’heure suivante.

EDIT 2 : Bon, même si le problème n’est pas totalement résolu, toutes vos réponses m’aident bien. Du coup, je fais de nouvelles recherches avec de nouveaux termes et je tombe sur de nouveaux sujets que je n’avais pas lu auparavant. C’est plutôt sympathique ça. Merci. :)

+0 -0

Aussi, quand vous parlez de pinger, c’est pinger une IP ou une IP ET un port ?

En udp, donc tu ping forcément une ip et un port qui là est le port que tu veux garder ouvert. Ça porte effectivement à confusion avec la commande ping. ;)

EDIT : Après, j’ai une alternative. C’est pas génial, mais bon. Si je peux envoyer une commande directement après avoir reçu une réponse, je pourrais très bien envoyer les commandes dans un tableau. Une sorte de liste d’attente. Et dès qu’un objet me parle, je lui envoie tout de suite toutes les commandes qui lui sont associées. L’inconvénient, c’est que si elle ne répond que toutes les heures, la commande ne sera effectuée que l’heure suivante.

Ça se fait beaucoup pour les objets connectés, avec des MQTT comme rabbitMQ. ;)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte