ESP8266 NodeMCU TCP Socket Server Arduino Example

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,
 * 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() 
  pinMode(SendKey,INPUT_PULLUP);  //Btn to send data

  WiFi.begin(ssid, password); //Connect to wifi
  // Wait for connection  
  Serial.println("Connecting to Wifi");
  while (WiFi.status() != WL_CONNECTED) {   

  Serial.print("Connected to ");

  Serial.print("IP address: ");
  Serial.print("Open Telnet and connect to IP:");
  Serial.print(" on port ");
//                    Loop

void loop() 
  WiFiClient client = server.available();
  if (client) {
      Serial.println("Client Connected");
        // read data from the connected client
      //Send Data to connected client
    Serial.println("Client disconnected");    


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]

NodeMCU TCP Socket Server

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.

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.

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.

2 thoughts on “ESP8266 NodeMCU TCP Socket Server Arduino Example

    1. Using client array

      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() {

      // Connect to WiFi network
      Serial.print(“Connecting to “);
      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
      Serial.println(“WiFi connected”);

      // Start the server
      Serial.println(“Server started”);

      // Print the IP address

      void loop() {
      WiFiClient newClient = server.available();
      if (client) {
      Serial.println(“new client”);
      // Find the first unused space
      for (int i=0 ; iavailable() ) {
      // 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

      // If you want to disconnect the client here, then do this:
      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 🙂


Leave a Reply