In this tutorial we are making ESP8266 NodeMCU as TCP Socket Server for bidirectional communication. Before we start directly on Socket programming let’s have some understanding of what is TCP Socket.
TCP Socket
Socket communication is a way of connecting two nodes on a network to communicate with each other. One socket(node) listens on a particular port at an IP, while other socket reaches out to the other to form a connection. Server forms the listener socket while client reaches out to the server. Low level communication is used in most of the industrial applications and for continuous data transfer.
Whats the difference between HTTP and TCP communication ?
TCP is a transfer protocol. HTTP is built on top of TCP, meaning that every HTTP request uses TCP as its transfer protocol. Other application protocols can use TCP as their transport protocol as well. See the OSI model for more on the theory of network protocols. The basic idea is that TCP (a transfer protocol) is lower-level than HTTP (an application protocol which happens to use TCP).
Every HTTP server you create is necessarily also a TCP server (in the sense that it is a server using TCP as its transfer protocol).
ESP8266 NodeMCU Code for TCP Socket Server
Enter Your WiFi SSID and Password and upload code to NodeMCU
/* * Copyright (c) 2018, circuits4you.com * All rights reserved. * Create a TCP Server on ESP8266 NodeMCU. * TCP Socket Server Send Receive Demo */ #include <ESP8266WiFi.h> #define SendKey 0 //Button to send data Flash BTN on NodeMCU int port = 8888; //Port number WiFiServer server(port); //Server connect to WiFi Network const char *ssid = "---------"; //Enter your wifi SSID const char *password = "--------"; //Enter your wifi Password int count=0; //======================================================================= // Power on setup //======================================================================= void setup() { Serial.begin(115200); pinMode(SendKey,INPUT_PULLUP); //Btn to send data Serial.println(); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); //Connect to wifi // Wait for connection Serial.println("Connecting to Wifi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); delay(500); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); server.begin(); Serial.print("Open Telnet and connect to IP:"); Serial.print(WiFi.localIP()); Serial.print(" on port "); Serial.println(port); } //======================================================================= // Loop //======================================================================= void loop() { WiFiClient client = server.available(); if (client) { if(client.connected()) { Serial.println("Client Connected"); } while(client.connected()){ while(client.available()>0){ // read data from the connected client Serial.write(client.read()); } //Send Data to connected client while(Serial.available()>0) { client.write(Serial.read()); } } client.stop(); Serial.println("Client disconnected"); } } //=======================================================================
Testing
Upload above code and open serial monitor first to get the IP address of ESP8266. Then Open Telnet program to test the communication.
Step 1: Get IP from serial monitor and Connect to ESP using telnet [192.168.xx.xx IP] [port]
Step 2: Observe serial monitor
Step 3: Send Some data from telnet
Step 4: Send some data from serial monitor
Advantages of using TCP Socket programming
As noted above, the primary purpose of TCP is to provide reliable logical circuit or connection service between pairs of processes. It does not assume reliability from the lower-level protocols (such as IP) so TCP must guarantee this itself.
TCP can be characterized by the following facilities it provides for the applications using it:
Stream Data Transfer
From the application’s viewpoint, TCP transfers a contiguous stream of bytes through the internet. The application does not have to bother with chopping the data into basic blocks or datagrams. TCP does this by grouping the bytes in TCP segments, which are passed to IP for transmission to the destination. Also, TCP itself decides how to segment the data and it may forward the data at its own convenience.
Sometimes, an application needs to be sure that all the data passed to TCP has actually been transmitted to the destination. For that reason, a push function is defined. It will push all remaining TCP segments still in storage to the destination host. The normal close connection function also pushes the data to the destination.
Reliability
TCP assigns a sequence number to each byte transmitted, and expects a positive acknowledgment (ACK) from the receiving TCP. If the ACK is not received within a timeout interval, the data is retransmitted. As the data is transmitted in blocks (TCP segments) only the sequence number of the first data byte in the segment is sent to the destination host.
The receiving TCP uses the sequence numbers to rearrange the segments when they arrive out of order, and to eliminate duplicate segments.
Flow Control
The receiving TCP, when sending an ACK back to the sender, also indicates to the sender the number of bytes it can receive beyond the last received TCP segment, without causing overrun and overflow in its internal buffers. This is sent in the ACK in the form of the highest sequence number it can receive without problems. This mechanism is also referred to as a window-mechanism.
Multiplexing
Is achieved through the use of ports, just as with UDP.
Logical Connections
The reliability and flow control mechanisms described above require that TCP initializes and maintains certain status information for each data stream”. The combination of this status, including sockets, sequence numbers and window sizes, is called a logical connection. Each connection is uniquely identified by the pair of sockets used by the sending and receiving processes.
Full Duplex
TCP provides for concurrent data streams in both directions.
How can we have multiple socket connection from different laptop terminal to one single esp8266
Using client array
#include
const char* ssid = “your-ssid”;
const char* password = “your-password”;
#define MAX_CLIENTS 10
#define MAX_LINE_LENGTH 50
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
WiFiClient *clients[MAX_CLIENTS] = { NULL };
char inputs[MAX_CLIENTS][MAX_LINE_LENGTH] = { 0 };
void setup() {
Serial.begin(115200);
delay(10);
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print(“Connecting to “);
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}
Serial.println(“”);
Serial.println(“WiFi connected”);
// Start the server
server.begin();
Serial.println(“Server started”);
// Print the IP address
Serial.println(WiFi.localIP());
}
void loop() {available() ) {
WiFiClient newClient = server.available();
if (client) {
Serial.println(“new client”);
// Find the first unused space
for (int i=0 ; i
// Read the data
char newChar = clients[i]->read();
// If we have the end of a string
// (Using the test your code uses)
if (‘\r’ == newChar) {
// Blah blah, do whatever you want with inputs[i]
// Empty the string for next time
inputs[i][0] = NULL;
// The flush that you had in your code – I’m not sure
// why you want this, but here it is
clients[i]->flush();
// If you want to disconnect the client here, then do this:
clients[i]->stop();
delete clients[i];
clients[i] = NULL;
} else {
// Add it to the string
strcat(inputs[i], newChar);
// IMPORTANT: Nothing stops this from overrunning the string and
// trashing your memory. You SHOULD guard against this.
// But I’m not going to do all your work for you 🙂
}
}
}
}