Différences entre versions de « Esp8266 udp server »
Ligne 128 : | Ligne 128 : | ||
= Serveur UDP multicast = | = Serveur UDP multicast = | ||
+ | Le [https://fr.wikipedia.org/wiki/Multicast multicast] permet de créer des groupes de diffusions, très pratiques pour parler à plusieurs équipements en ayant à envoyer qu'un seul paquet. | ||
+ | |||
+ | |||
Pour commencer, nous allons ajouter dans la partie des ''variables statiques'' les lignes suivantes : | Pour commencer, nous allons ajouter dans la partie des ''variables statiques'' les lignes suivantes : | ||
<source lang="c"> | <source lang="c"> | ||
Ligne 151 : | Ligne 154 : | ||
Serial.println(PORT); | Serial.println(PORT); | ||
</source> | </source> | ||
+ | On peut maintenant envoyer un message sur n'importe laquelle des deux adresses: | ||
+ | [[Fichier:Send packet udp esp multicast.png|700px|centré]] | ||
+ | = Pour aller plus loin = | ||
+ | La souscription à un groupe ''multicast'' devient nécessaire lorsque certains appareils ''parlent'' le même langage (protocole) car cela leurs permet de se reconnaître entre eux en échangeant des messages respectant un certain format. On peut prendre comme exemple les protocoles [https://fr.wikipedia.org/wiki/Cisco_Discovery_Protocol ''CDP''] ou [https://fr.wikipedia.org/wiki/Open_Shortest_Path_First#Paquets_OSPF_et_LSA ''OSPF'']. | ||
+ | C'est une alternative plus intéressante que le ''broadcast'' car cela permet de cibler uniquement les équipements parlant le même langage et donc intéressés par le message. | ||
+ | == Définition des messages == | ||
+ | Comme dans l'élaboration de n'importe quel protocole, avant d'aller plus loin, il faut commencer par définir la sémantique des messages: | ||
+ | * Les commandes : | ||
+ | ** HELO → permet de connaître l'adresse ''unicast'' de tous les intervenants; | ||
+ | ** SUBSW.X.Y.Z → ordonne à un équipement de souscrire au groupe ''multicast'' W.X.Y.Z; | ||
+ | ** EXIT → ordonne à un équipement de quitter le groupe ''multicast'' auquel il est abonné; | ||
+ | * Les acquittements : | ||
+ | ** ACK → acquittement généré suite à la réussite d'une commande; | ||
+ | ** NACK → acquittement généré suite à l'échec d'une commande; | ||
+ | == Définition des adresses == | ||
+ | Une fois les messages définis, il reste maintenant à décider d'une adresse ''multicast'' ou les équipements vont se retrouver. D'après l'[https://www.iana.org/ IANA] le groupe ''multicast'' à utiliser sur un réseau local doit se trouver dans la plage ''239.0.0.0/8'', nous pouvons donc conserver l'adresse ''239.0.0.50'' comme adresse ''multicast'' de découverte. |
Version du 28 janvier 2018 à 21:26
Introduction
Soyez sûr de comprendre la section sur comment écrire un sketch avant de poursuivre. Le code ci-dessous fait référence à des parties bien spécifiques, détaillées et expliquées dans la section suscitée. De plus, il est impératif d'avoir configuré la puce comme client WiFi ! |
Dans cet exemple, nous allons créer un serveur UDP qui va écouter les messages en unicast et multicast
Connexion au réseau
Commençons par nous connecter à un réseau en utilisant le DHCP :
#include <ESP8266WiFi.h>
const char ssid[] = "e900";
const char password[] = "********";
void setup() {
// on démarre le port série
Serial.begin(115200);
// On attend "un peu" que le buffer soit prêt
delay(10);
// On efface la configuration précédente
WiFi.disconnect(true);
// Initialisation de la connection
WiFi.begin(ssid, password);
// Test pour déterminer quand la connection est prete
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
// Affichage des informations
Serial.print("\nConnecte a ");
Serial.print(ssid);
Serial.print(" avec l'ip ");
Serial.println(WiFi.localIP());
}
void loop() {
}
Le code précédent vous donne le résultat suivant sur le port série :
Connecte a e900 avec l'ip 192.168.1.188
Serveur UDP unicast
Création du serveur
Nous allons maintenant ajouter la partie écoute en UDP.
Dans la partie des imports ajoutez la ligne suivante :
#include <WiFiUDP.h>
Dans la partie des variables statiques ajoutez les lignes suivantes :
// Port d'écoute UDP
const uint16_t PORT = 4321;
// Taille du tampon de réception
const uint16_t BUFFER_SIZE = 512;
// Tampon de réception
char buffer[BUFFER_SIZE];
// L'instance du serveur UDP
WiFiUDP udp;
A la fin de la fonction setup() nous allons ajouter la ligne suivante :
// Démarrage de l'écoute
udp.begin(PORT);
Serial.print("Démarrage de l'ecoute sur le port ");
Serial.println(PORT);
Récupération et affichage des paquets
Pour récupérer et afficher le contenu du paquet, nous allons créer une fonction :
void readPacket() {
uint16_t len = udp.available();
Serial.print("Paquet de ");
Serial.print(len);
Serial.print(" octets recu de ");
Serial.print(udp.remoteIP());
Serial.print(":");
Serial.print(udp.remotePort());
Serial.print(" contenant '");
// Mise en tampon du paquet
udp.read(buffer, len);
// Affichage du contenu du paquet
for (int i = 1; i <= len; i++) {
Serial.print(buffer[i - 1]);
}
Serial.println("'");
}
Que nous allons appeler dans la fonction loop():
void loop() {
if (udp.parsePacket() > 0) {
readPacket();
}
}
Il est désormais possible, en utilisant un logiciel comme Packet Sender d'envoyer un paquet à notre ESP:
Lorsque vous appuyer sur send, vous devriez voir le message suivant s'afficher dans la console :
Paquet de 11 octets recu de 192.168.1.1:62971 contenant 'Hello World'
Envoie d'un paquet UDP
Maintenant que nous recevons les paquets, il faudrait que nous puissions répondre ! Pour cela nous allons créer la fonction suivante :
void sendPacket(const char content[], IPAddress ip, uint16_t port) {
udp.beginPacket(ip, port);
udp.write(content);
udp.endPacket();
}
Pour créer un serveur echo, après la ligne:
readPacket();
Il nous suffit d'ajouter:
sendPacket(buffer, udp.remoteIP(), udp.remotePort());
On a maintenant une réponse de l'ESP:
Serveur UDP multicast
Le multicast permet de créer des groupes de diffusions, très pratiques pour parler à plusieurs équipements en ayant à envoyer qu'un seul paquet.
Pour commencer, nous allons ajouter dans la partie des variables statiques les lignes suivantes :
// Adresse IP multicast
const IPAddress IP_MCAST(239, 0, 0, 50);
Ensuite, dans la fonction setup(), nous allons remplacer les lignes suivantes :
// Démarrage de l'écoute
udp.begin(PORT);
Serial.print("Démarrage de l'ecoute sur le port ");
Serial.println(PORT);
par les lignes :
// Démarrage de l'écoute en multicast
udp.beginMulticast(WiFi.localIP(), IP_MCAST, PORT);
Serial.print("Demarrage de l'ecoute sur les adresses ");
Serial.print(WiFi.localIP());
Serial.print(" et ");
Serial.print(IP_MCAST);
Serial.print(" sur le port ");
Serial.println(PORT);
On peut maintenant envoyer un message sur n'importe laquelle des deux adresses:
Pour aller plus loin
La souscription à un groupe multicast devient nécessaire lorsque certains appareils parlent le même langage (protocole) car cela leurs permet de se reconnaître entre eux en échangeant des messages respectant un certain format. On peut prendre comme exemple les protocoles CDP ou OSPF. C'est une alternative plus intéressante que le broadcast car cela permet de cibler uniquement les équipements parlant le même langage et donc intéressés par le message.
Définition des messages
Comme dans l'élaboration de n'importe quel protocole, avant d'aller plus loin, il faut commencer par définir la sémantique des messages:
- Les commandes :
- HELO → permet de connaître l'adresse unicast de tous les intervenants;
- SUBSW.X.Y.Z → ordonne à un équipement de souscrire au groupe multicast W.X.Y.Z;
- EXIT → ordonne à un équipement de quitter le groupe multicast auquel il est abonné;
- Les acquittements :
- ACK → acquittement généré suite à la réussite d'une commande;
- NACK → acquittement généré suite à l'échec d'une commande;
Définition des adresses
Une fois les messages définis, il reste maintenant à décider d'une adresse multicast ou les équipements vont se retrouver. D'après l'IANA le groupe multicast à utiliser sur un réseau local doit se trouver dans la plage 239.0.0.0/8, nous pouvons donc conserver l'adresse 239.0.0.50 comme adresse multicast de découverte.