Différences entre versions de « Arduino W5100 web server »
Ligne 11 : | Ligne 11 : | ||
= Ethernet : utilisation d'un serveur = | = Ethernet : utilisation d'un serveur = | ||
− | Il est possible de démarrer un serveur qui écoutera sur un port précis | + | Il est possible de démarrer un serveur qui écoutera sur un port précis qui, dans notre cas de figure, utilisera le port ''TCP 80''. Dans un premier temps, nous allons récupérer la requête qui vient du client pour voir comment elle est formatée. Dans un deuxième temps, on verra comment on pourra traiter et formuler une réponse. |
== Récupération de la requête == | == Récupération de la requête == | ||
===variables globales=== | ===variables globales=== |
Version du 11 janvier 2017 à 09:50
Introduction
Il faut prendre connaissance du module W5100 et s'assurer que le module possède une configuration de niveau 3 OSI. 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. |
Ethernet : utilisation d'un serveur
Il est possible de démarrer un serveur qui écoutera sur un port précis qui, dans notre cas de figure, utilisera le port TCP 80. Dans un premier temps, nous allons récupérer la requête qui vient du client pour voir comment elle est formatée. Dans un deuxième temps, on verra comment on pourra traiter et formuler une réponse.
Récupération de la requête
variables globales
// Serveur écoutant sur le port 80
EthernetServer server(80);
setup()
// Démarrage du serveur
server.begin();
loop()
// On écoute les connections entrantes
EthernetClient client = server.available();
// Si la connection est établie (SYN / SYN+ACK / ACK)...
if (client) {
Serial.println(F("---- new request ----"));
// ...pendant que le client maintient la session TCP...
while (client.connected()) {
// ...et que la requête contient des caractères...
if (client.available()) {
// ...on récupére les caractères...
char c = client.read();
// ... et on les affiche sur le terminal série
Serial.print(c);
}
}
// Fin de la requête
Serial.println(F(""));
Serial.println(F("---- end request ----"));
}
}
Lorsque l'on entre dans la barre de recherche du navigateur l'adresse IP du module Ethernet on a, après le timeout TCP, le résultat suivant :
---- new request ---- GET / HTTP/1.1 Host: 192.168.1.26 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 ---- end request ----
On constate que :
- la requête démarre par le verbe HTTP (ici GET) suivit de l'URL (ici /) et du protocole (ici HTTP/1.1) ;
- la requête contient toutes les entêtes envoyés par le navigateur ;
- la requête se termine par deux sauts de ligne.
Pour terminer proprement la requête HTTP, il suffit de mettre fin à la session TCP à réception des deux sauts de ligne.
Traitement de fin de requête
On va écrire un programme qui attend le saut de ligne (\n) à la fin d'une ligne vide.
loop()
// On écoute les connections entrantes
EthernetClient client = server.available();
// Si la connection est établie (SYN / SYN+ACK / ACK)...
if (client) {
// Nos deux compteurs
uint8_t nbNewLine = 0, bytesOnLine = 0;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c != '\r') {
if (c == '\n') {
// Fin de ligne
if (bytesOnLine == 0) {
// Ligne vide on incrémente le conteur
nbNewLine++;
if (nbNewLine == 1) {
// Deuxième ligne vide = fin requête
// Envoie du status HTTP, ici '200 OK'
client.println("HTTP/1.1 200 OK");
// Entête spécifiant le contenu du corps
client.println("Content-Type: text/html");
/**
On prévient le client qu'à la fin de
la requête, on coupe la session TCP
*/
client.println("Connection: close");
// Spération entre les entêtes HTTP et le corps du message
client.println();
// contenu HTML
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("It Works !");
client.println("</html>");
// On donne le temps au navigateur de traiter le message
delay(1);
// Fermeture de la session TCP
client.stop();
break;
}
} else {
// Ligne contenant des caractères, on remet le conteur à zéro
bytesOnLine = 0;
}
} else {
/**
On reçoit des caractères autre que \r et \n
alors on incrémente le conteur de caractères
*/
bytesOnLine++;
}
}
}
}
// Fin de la requête
Serial.println(F(""));
Serial.println(F("---- end request ----"));
}
A partir de maintenant, côté navigateur, la requête se termine proprement et on attend plus le timeout TCP. Il faudrait maintenant, digérer l'URL pour pouvoir répondre en fonction de la requête !
Digestion de l'URL
A partir de maintenant, le code devient trop complexe pour résider dans la fonction loop(). Il faut donc le fragmenter en plusieurs fonctions qui seront appelées dans loop().