Programming The ESP32 In C - Socket Web Client |
Written by Harry Fairhead | ||||
Tuesday, 22 October 2024 | ||||
Page 3 of 3
The web uses the HTTP protocol and this is essentially a set of text headers that tell the server what to do, and a set of headers that the server sends back to tell you what it has done. The most basic transaction the client can have with the server is to send a GET request for the server to send a particular file. Thus the simplest header is: char header[] = "GET /index.html HTTP/1.1\r\n\r\n"; which is a request for the server to send index.html. However, in most cases we need one more header, HOST, which gives the domain name of the server. Why do we need to do this? Simply because HTTP says you should and many websites are hosted by a single server at the same IP address. Which website the server retrieves the file from is governed by the domain name you specify in the HOST header. This means that the simplest set of headers we can send the server is: char header[] = "GET /index.htm HTTP/1.1\r\n HOST:example.com\r\n\r\n"; which corresponds to the headers: GET /index.html HTTP/1.1 HOST:example.com An HTTP request always ends with a blank line. If you don't send the blank line then you will get no response from most servers. In addition the HOST header has to have the domain name with no additional syntax - no slashes and no http: or similar. With the headers defined we can send our first HTTP request using write as if the socket was just another file to write data to: int n = write(sockfd, header, strlen(header)); and, of course, to use the strlen function we need to add: #include <string.h> The server receives the HTTP request and should respond by sending the data corresponding to the file specified, i.e. index.html. We can read the response just as if the socket was a file: char buffer[2048]; n = read(sockfd, buffer, 2048); printf("%s", buffer); You can make this more complicated by checking the number of bytes read and reading more if the buffer is full, but this is a simple and direct way to get the HTML. In fact, you get more than the HTML as you get the entire HTTP response including the response headers: HTTP/1.1 200 OK Accept-Ranges: bytes Age: 483961 Cache-Control: max-age=604800 Content-Type: text/html; charset=UTF-8 Date: Wed, 14 Aug 2024 08:49:49 GMT Etag: "3147526947+gzip" Expires: Wed, 21 Aug 2024 08:49:49 GMT Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT Server: ECAcc (nyd/D169) Vary: Accept-Encoding X-Cache: HIT Content-Length: 1256 <!doctype html> <html> and so on... Notice the blank line marking the end of the header and signaling that the data payload follows. The complete program is: #include <stdio.h> #include "freertos/FreeRTOS.h" #include "esp_wifi.h" #include "nvs_flash.h" #include "esp_event.h" #include "esp_netif.h" #include "string.h" #include "socket.h" #include "wificonnect.h" void app_main(void) { wifiConnect("CO", "ssid", "password"); while (wifiStatus != 1010) { vTaskDelay(10 / portTICK_PERIOD_MS); }; int sockfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addr;addr.sin_family = AF_INET; addr.sin_port = htons(80); addr.sin_addr.s_addr = 0x0Ed7b85d; if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0)return; char header[] = "GET /index.html HTTP/1.1\r\n Host:example.com\r\n\r\n"; int n = write(sockfd, header, strlen(header)); char buffer[2048]; n = read(sockfd, buffer, 2048); buffer[n] = 0; printf("%s\n", buffer); }
Of course, we can do much better than this simple example. For one thing, each socket operation needs to be checked for errors. Here we only check for the most likely error, that the server refused the connection. In book but not in this extract:
Summary
Programming The ESP32 In C
|
||||
Last Updated ( Tuesday, 22 October 2024 ) |