0

$USD

$USD
TUTORIALS ESP32Arduino

ESP32 Arduino Tutorial Socket server: Getting remote client IP

DFRobot Jun 14 2018 2727

Introduction

In this tutorial, we will check how to get the IP of a socket client that connects to a socket server hosted on the ESP32, using the Arduino core.

You can check a detailed tutorial on how to set a socket server on the ESP32 on this previous tutorial. If you want to learn how to develop a socket client on the ESP32, then please consult this tutorial.

In this tutorial, since the ESP32 will be working as a server, we will need to develop a socket client to contact it. We will do it in Python, since it is very simple to set a socket client on this language.

If you don’t feel comfortable with Python development, then you can skip that section and use a web browser as socket client instead. Details on how to use the browser to reach the ESP32 socket server are explained at the end of the “Testing the Code” section.

The tests were performed using a DFRobot’s ESP32 module integrated in a ESP32 development board.


The Python code

First of all, we need to import Python’s socket module, which we will use to create a socket client and connect to the ESP32 server.

import socket

Next we need to create an object of class socket. This object will expose the methods we need to connect to the server and send data to it.

sock = socket.socket()

Now we will assign the IP address and port of the ESP32 server to two variables, since we are going to need this information to contact the server. If you don’t know the IP of your your ESP32 in your local network, we will print it later on the Arduino code. You should copy it and use it here.

Note that below I’m using the IP of my ESP32 on my local network. Yours will most likely be different.

We will use port 80 for the server and this value is set by us on the Arduino code, so it doesn’t depend on the network.

host = "192.168.1.78"
port = 80

To establish the connection to the server, we call the connect method on the socket object, passing as argument a tuple with the host and port we have just declared.

sock.connect((host, port))

To send some data, we need to call the send method on the socket object and pass as input the content to be sent to the server. We will send a simple string.

sock.send("test")

Finally, we call the close method on the socket object to close the connection and free the resources.

sock.close()

The final Python code can be seen below.

import socket               

sock = socket.socket()

host = "192.168.1.78" #ESP32 IP in local network
port = 80             #ESP32 Server Port    

sock.connect((host, port))
sock.send("test")
sock.close()


The Arduino code

The Arduino code will be very simple. We are going to focus on getting the remote client IP, so we are not going to establish any exchange of data with it.

As usual, since we need to make our ESP32 reachable by clients, we will need to connect it to a WiFi network. This means we need to include the WiFi.h library and declare two variables to hold the network credentials (password and network name).

We will also need an object of class WiFiServer, which we will use to set the server and receive incoming socket client connections.

The constructor of this class receives as input the port where the server will be listening. As we have seen while writing the Python code, we will use port 80. Nonetheless, you can test with other ports, as long as you update the Python code accordingly.

#include "WiFi.h"

const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";

WiFiServer wifiServer(80);

Moving on to the Arduino setup, we start by opening a serial connection to output the results of our program and then we connect the ESP32 to the WiFi network using the previously declared credentials.

After the connection is established, we need to start the socket server, so it receives incoming requests. This is done by calling the begin method. This method receives no arguments and return void.

You can check the full setup function below.

void setup() {

  Serial.begin(115200);

  delay(1000);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println("Connected to the WiFi network");
  Serial.println(WiFi.localIP());

  wifiServer.begin();
}

Moving on to the Arduino loop, we can check if a client has connected to the server by calling the available method on the WiFiServer object. This method receives no parameters and as output it returns an object of class WiFiClient.

WiFiClient client = wifiServer.available();

Note that by default this is a non blocking call, which means that it will return a WiFiClient object even if no client has connected to the server.

We can check if a client is indeed connect by either calling the connected method on the WiFiClient object or by enclosing the object in a IF condition. This last option is possible because in this class the C++ bool operator is overloaded and it calls the connected method and returns its value.

We will use the second approach and inside the IF block we know that the client is indeed connected. Thus, we can get the IP of the client by calling the remoteIP method on the WiFiClient object.

This method takes no arguments and returns the IP of the client, which we will print to the serial connection.

Serial.println(client.remoteIP());

As mentioned before, we will not exchange any data with the client, so we can simply close the connection after getting the IP. We do this by calling the stop method on the WiFiClient object.

client.stop();

The final Arduino code can be seen below. It contains some additional prints and a small delay between each iteration of the Arduino main loop.

#include "WiFi.h"

const char* ssid = "yourNetworkName";
const char* password =  "yourNetworkPassword";

WiFiServer wifiServer(80);

void setup() {

  Serial.begin(115200);

  delay(1000);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println("Connected to the WiFi network");
  Serial.println(WiFi.localIP());

  wifiServer.begin();
}

void loop() {

  WiFiClient client = wifiServer.available();

  if (client) {

    Serial.print("Client connected with IP:");
    Serial.println(client.remoteIP());

    client.stop();

  }

delay(100);
}


Testing the code

To test the whole system, we start by compiling and uploading the ESP32 code. Once the procedure finishes, simply open the Arduino IDE serial monitor.

As soon as the connection to the WiFI network is established, the local IP of the ESP32 on the network should get printed to the serial port, as indicated in figure 1. If you haven’t yet done so, then copy this IP and assign it in the Python code to the host variable.

ESP32 Arduino Printing the Local IP after wifi connection.png

Figure 1 – Local IP assigned to the ESP32.

Then, run the Python code, so the socket client establishes the connection to the server. Once the program finishes running, go back to the Arduino IDE serial monitor.

You should get an output similar to figure 2, which shows the IP of the remote client. In my case, I’ve tested running the Python code from two different machines, which is why I’m getting two distinct IPs.

ESP32 Arduino Socket Server Get Remote Client IP.png

Figure 2 – Output of the program, showing the remote clients’ IPs.

Note that the IP that gets printed should match the local IP of the computer where you are running the Python code. You should be able to get your machine’s local IP on this website.

Alternatively, you can open a command line and run the ipconfig command if you are on Windows or the ifconfig command if you are on Linux, and get the local IP of the computer.

Just as a final note, you don’t feel comfortable with developing and running Python code, you can use a web browser as a socket client to reach the ESP32 server. To do it, simply open a web browser of your choice and type the following, changing #yourESPIp# by the IP address of your ESP32, which was printed on the Arduino IDE serial monitor:

http://#yourESPIp#/

On your browser you should get an error message or something similar, but if you go back to the ESP32 serial monitor then an output similar to the one illustrated in figure 2 should be printed, indicated a socket client has indeed connected to the ESP32.

This is because HTTP actually works on top of sockets. So, when a browser contacts a website, it establishes a socket connection with it and the HTTP protocol data is sent over that socket.

Naturally, since our ESP32 socket server doesn’t know how to answer to the HTTP request made by the browser, then the browser presents an error.