ESP32 Arduino Tutorial: Setting a socket server

Introduction

The objective of this post is to explain how to create a simple socket server on the ESP32, using the Arduino core. It will act as an echo server which will return back to the client any content it sends.

In order to test our server, we will develop a very simple Python socket client. The Python version used was 2.7 and the code was tested on Windows 8.

The Python code

We will start our code by importing the Python socket module, which will allow us to connect to the ESP32 server.

import socket

Next we will create an object of class socket, which has the methods needed to connect to the server.

sock = socket.socket()

To connect to the server, we will need to know both its IP and the port where it is listening for incoming connections. We will store both values in two variables.

For the port, we will use 80 (we will set it to the same value on the Arduino code).

For the IP, we will need to use the one assigned to our ESP32 upon connecting to the WiFi network. If you don’t know the local IP of your ESP32 when it connects to your network, you can use a dummy value for now, since we will later print its value on the Arduino code.

host = "192.168.1.78"
port = 80

To perform the actual connection, we will now call the connect method on our socket object and pass as input a tuple with the host and the port.

sock.connect((host, port))

Since the ESP32 will act as an echo server, we will send it a message and then get the result back. To send a message to the server, we will simply call the send method of the socket object and pass as input the content. In this case, we will send a simple “hello world” message.

message = "Hello World"
sock.send(message)

We will now get content from the server until the whole message we have sent is echoed back to us.

To get data, we call the recv method of the socket object. This method receives as input a number with the maximum amount of data that can be received at once and returns a string representing the data received [1] (I’m using Python 2.7, but some Python versions return a byte object rather than a String).

Since we know that the server will echo the message back, we want to receive as much data as we sent. So, we will declare an empty string and keep asking for data and append it to that string until its size is equal to the size of the string we sent.

We will specify 1 for the input argument of the recv method, so we know that each call will return a string with only one character.

The Arduino code

We start our code by importing the WiFi.h library, in order for us to be able to connect the ESP32 to a WiFi network.

#include <WiFi.h>

Next we will declare two global variables to store the WiFi network credentials, more precisely, the network name (ssid) and the password. You should place here the credentials for the WiFi network you are going to connect to.

Now that we have finished the setup function, we will handle the actual client connections and data exchange on the Arduino main loop.

To start, we will check if a client has connected by calling the available method on our WiFiServer global object. This method takes no arguments and returns an object of class WiFiClient.

WiFiClient client = wifiServer.available();

Next, we need to check if a client is indeed connected. We can do this both by calling the connected method of the WiFiClient object or by checking that object with an IF condition. Note that the connected method returns true if a client is connected and false otherwise.

Regarding the second option of enclosing the WiFiClient object inside an IF condition, this is possible because in the implementation of the class, the C++ bool operator is overloaded and it actually calls the connected method and returns its value.

Note that operator overloading is an advanced feature of the C++ language (which is the language on top of which Arduino is built) that we don’t need to worry about and I’m just mentioning this for information.

if (client) {
// Data exchange with the client
}

If the previous condition is true, we will then start a loop while the client is connected. In this case, we will explicitly call the connected method of the WiFiClient object.

When the previous loop breaks, it means the client is no longer connected. Thus, we call the stop method on our WiFiClient to free all the resources and then print a message indicating the client disconnected.

Testing the code

To test the whole system, simply upload the code to your ESP32 using the Arduino IDE. Then open the IDE serial monitor and copy the IP address that gets printed upon a successful connection of the ESP32 to the WiFi network. That is the IP that should be used on the Arduino code.

Next, with the ESP32 already running the server code, run the Python code. You should get an output similar to figure 1, which shows the data sent to the server being echoed back, as expected.

Figure 1 – Output of the Python client program.

If you go back to the serial monitor, a message indicating that the client disconnected should be printed, as shown in figure 2. This indicates that the server correctly detected that the client is no longer connected, which is the expected behavior after the Python code calls the close method to end the connection.