ESP-IDF: TCP Server on ESP32
|Introduction:
In IoT, it is important to connect two components using server. Typical way is to use HTTP protocol, because it is easy and became defacto standard. However in constrained edge devices like ESP32, each bit counts, hence we need to look for lighter server component . Essentially HTTP is an application layer which runs on top of TCP/IP layer. TCP is two layers below the application protocol and hence uses less resources. Thus using TCP/IP will be efficient way for making server. Other aspect is in case of HTTP , client is always browser. In IOT usecases,it is not necessary to have browser as an interface as two embedded devices may need to talk.
It’s amazing how this little devices can perform several roles. Though ESP32 might not be able to serve many clients at the same time ,it is good enough to provide a simple interface for tasks such changing the WiFi configuration or to view some readings device took using different sensors connected to it.
Objective : To run lighter web server using TCP/IP protocol on ESP 32 using IDF as programming language.
We have seen how to use ESP32 as a TCP client in the previous post. Similar to ESP8266 (NodeMCU) we can run TCP server in two modes. You can see more about running TCP server on NodeMCU in one my post on NodeMCU. If you are just getting started with ESP32, I recommend you this post first.
Solution Approach :
There are two different methods for hosting TCP webserver. Depending on the need, one can choose any method. Nevertheless, we shall cover both the methods in this blogpost.
- ESP32 runs TCP server and provides a network for clients to connect (ESP32 will act as a access point)
- ESP32 runs TCP server and connects to a network we provide (ESP32 will act as WiFi client device and joins user specified network)
Base code for opening a socket and accepting connections remains same in both methods. We will use the socket API provided by lwIP (lightweight IP). We have all ready seen some the API in TCP Client post.
Solution Overview diagram

Create TCP Socket
socket(domain, type, protocol)
This step is same for both TCP client and TCP server.
The first parameter is communication domain for which we are creating the domain, here it is AF_INET. Second parameter is socket type it can be SOCK_STREAM/SOCK_DGRAM/SOCK_SEQPACKET. Third parameter specifies the protocol (if we pass 0, lib will select the appropriate protocol)
Binding the socket
bind(socket,srvr_address,address_lenght)
bind() function lets us assign a local protocol address (here it is IP and PORT) to the socket
Start listening for incoming connections
listen(socket,backlog)
listen() function makes the socket as passive and ready for incoming connections, we have provide socket and backlog as arguments. The backlog argument indicate maximum number of requests that can be queued for this socket. If the queue exceeds this length, the new connection requests will be rejected.
Accept connection
accept(socket,client_address,address_lenght)
accept() is blocking method, it will not return until a new connection request is made. It will provide a new socket descriptor and the address of the client from whom this request came.
read from the socket
read(socket,buffer,size_of_buffer)
read function, read available data from the socket and returns the number bytes written to buffer
write to socket
write(socket,message,message_len)
write method accepts socket, message and length of the message (in the same order). It writes the given message to the socket
close the socket
close(socket)
closes the given socket
ESP32 : TCP Server and Access Point
In this mode ESP32 has to provide both TCP server and access point. You can check out this post on how to put the ESP32 in Access Point mode. TCP server will wait for the AP to start, once the AP is ready, it will open the port for incoming connections.

On every new request, ESP will print the request contents and responds with a “Hello World” message. This is not HTTP server, the response will be just a string not a html content.
To test the server we will use nodejs tcp client, it will open connection to (192.168.1.1:3000) and prints the received message. You need to connect to the AP created by ESP before testing the server

You can also send a request from browser to 192.168.1.1:3000, ESP32 will print the request content, but the browser will complain that received content is not HTML (we are not sending proper HTML content from server).
ESP32 : TCP Server and WiFiClient
In STA mode, ESP32 will first connect to a WiFi Access Point, then starts the server. ESP will print the IP it got from the router, we need this IP to make send message to the ESP.

The TCP Server code is will remain same for both the modes (instead of waiting for AP to start , here we will wait for IP from router). We will add the TCP server code to WiFi client connect code we developed in one of the previous post. Make sure to change to place the ESP IP in nodejs_tcp_client.js file before running it.

full code is available at this git repo
Conclusion :
Using ESP 32 as TCP as major advantage of using less resources as that of hosting HTTP webserver. The usecases that can make use of TCP server can be many. Comment your thoughts/questions on TCP server on ESP32
I used AP mode. I am always getting connection refused over tcp. I tested with android socket app, nodejs code in linux and python socket programs too..
Hi, make sure that the system is connected to AP created by ESP32. Please post the log printed on esp32 console ,and the program you are using to test the connection if thats ok with you
Heyy. Got it worked. Thanks. There was some issue from my side of code.
hi,
could anyone help regarding for the code.. mean i want to send the data from nodemcu(client) to another nodemcu(server) with tcp protocol by using lm35 with embedded c but i am very poor in programming langu. can anyone help me regarding the code..