Communication between devices that doesn’t require a server (TCP code examples)
TCP packet communication
Instead of implementing a “full” web server, I decided to go to a simpler TCP server – client connection. This eliminates overhead in the protocol but as well limits the usage. It is not possible to just use a browser (Chrome, Firefox, …) to send commands to a device. But I was not planing to use browsers anyway.
TCP client (control device) example for ESP8266
To be able to send a packet over TCP it is only necessary to start a WiFiClient, connect to the server (here on port 9998) and send the packet.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/** sendCmd Send a packet to a device over TCP Returns true if request could be sent or false if connection failed */ bool sendCmd(IPAddress serverIP, String deviceCmd) { /** WiFiClient class to create TCP communication */ WiFiClient tcpClient; if (!tcpClient.connect(serverIP, 9998)) { if (debugOn) { String debugMsg = "connection to " + String(serverIP[0]) + "." + String(serverIP[1]) + "." + String(serverIP[2]) + "." + String(serverIP[3]) + " failed"; Serial.println(debugMsg); } tcpClient.stop(); return false; } tcpClient.print(deviceCmd); tcpClient.stop(); return true; } |
TCP server (sensor/actuator device) example for ESP8266
To run the TCP server part, we define a WiFiServer and start the listening to port 9998 in setup(). In loop() we check if a client has established a connection. If there is a connection, we receive the payload (with a 3 seconds timeout) and then parse the payload.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#include <ESP8266WiFi.h> /** WiFiServer class to create TCP socket server on port 9998*/ WiFiServer tcpServer(9998); void setup(void) { // Some initialization stuff // Start the tcp socket server to listen on port tcpComPort tcpServer.begin(); } void loop(void) { // here is your code that is processed in a loop // Handle new request on tcp socket server if available WiFiClient tcpClient = tcpServer.available(); if (tcpClient) { long timeoutStart = now(); char recvdBuffer[128]; byte index = 0; char inByte; while (tcpClient.connected()) { if (tcpClient.available()) { inByte = tcpClient.read(); recvdBuffer[index] = inByte; index++; } if (now() > timeoutStart + 3000) { // Wait a maximum of 3 seconds break; // End the while loop because of timeout } } recvdBuffer[index] = 0; tcpClient.flush(); tcpClient.stop(); if (index != 0) { // Any data received? // Copy received buffer into a string for easier handling String payload(recvdBuffer); // parse the incoming data // toggle debugging if (payload.substring(0,1) == "d") { // toggle debug flag debugOn = !debugOn; if (debugOn) { Serial.println("Debug over TCP is on"); } else { Serial.println("Debug over TCP is off"); } return; // Reset device } else if (payload.substring(0, 1) == "x") { Serial.println("Reset device"); tcpClient.flush(); tcpClient.stop(); // Reset the ESP delay(3000); ESP.reset(); } } } } |
In this example I parse only for 2 commands, a simple toggle for the debug output and a command to reset the device.






