ESP32 wifi sockets

I am using an ESP32 to do some network stuff. I am using the WiFiClient library, and sending data works fine (the write() function can send one or multiple bytes). However, it seems that the read() function only reads one byte at a time. I could implement a while() to read all the bytes, but this seems very, very inefficient, especially on MCUs with limited CPU resources.

Is there some way (perhaps a different library) to work directly with sockets, or to be able to read multiple bytes at once in a single call?

you could use readBytes(), e.g.

on an ESP32

void loop() {
  static WiFiClient client;
  static int16_t seqExpected = 0;
  if (!client)
    client = server.available();  // Listen for incoming clients
  if (client) {                   // if client connected
    if (!alreadyConnected) {
      // clead out the input buffer:
      client.flush();
      Serial.println("We have a new client");
      alreadyConnected = true;
    }
    // if data available from client read and display it
    int length;
    float value;
    if ((length = client.available()) > 0) {
      //str = client.readStringUntil('\n');  // read entire response
      Serial.printf("Received length %d - ", length);
      // if data is correct length read and display it
      if (length == sizeof(value)) {
        client.readBytes((char*)&value, sizeof(value));
        Serial.printf("value %f \n", value);
      } else
        while (client.available()) Serial.print((char)client.read());  // discard corrupt packet
    }
  }
}

there's an overload..

 int read();
 int read(uint8_t *buf, size_t size);

WiFiClient

did a demo using udp, receives and sends a structure..
UDP Demo..

There's also a sender in that git..

Can also look through the lib for nards, it uses tcp..
nards lib..

have fun.. ~q

Thanks! You are right, I was looking at just part of the error message (where it complained that the function candidate had 0 parameters). Later on it was complaining about incompatible types, I had to cast a pointer which solved it. I am still a bit new to Arduino, I am used to work with sockets and lower level stuff :slight_smile:

Great, thanks! qubits-us pointed out that read() also has an overload for multiple bytes. Is there any difference between readBytes() and read()?

read() returns a single byte readBytes() returns a number of bytes

client.readBytes((char*)&value, sizeof(value));

the firdt parameter is a pointer to the destination byte array second parameter is the number of bytes to attempt to read - returns the number of bytes read from the stram
make sure you cast the destination to (byte*) or as above (char *)

But again, it seems that there are two version of read(), one which can read an arbitrary number of bytes.

C++ has function overloading where two or more functions can have the same name but different parameters.

Yes, I know that. I was just asking if there is a difference between those two functions (in terms of speed for example).

That doesn't exactly describe an ESP32.

Check out the inheritance chain:

class WiFiClient : public ESPLwIPClient
class ESPLwIPClient : public Client
class Client: public Stream

So, WiFiClient inherits indirectly from Stream. That mean you have all the functions defined in the Stream class available to you.

However, all that being said ....

Seeing as how data comes in over the WiFi interface byte-by-byte, I'm not sure what your objection is.

Well, I solved it, but the objection is twofold:

  1. The data should not come byte by byte, it should come in a buffer. I mean, it may come byte by byte at a very low level, but any WiFi hardware puts it in a buffer before being presented to the driver.
  2. Even if 1 were not true, calling a function millions of times to download a picture is very slow, even on a PC, let alone on a 240Mhz MCU.

All data comes byte by byte, of course, but yes it is buffered and you can read chunks..
But you do have to watch out for larger transfers, like pics, you can't read it all in one go, buffers are not larger enough, they will be sent in chunks the size of the current MTU of the network, usually around 1,500 bytes..
You need to create a buffer to store entire size and read in chunks and add to your buffer..
I noticed this when I added ota to nards, was toying with different buffer sizes, when i went over the MTU size, things got funny..
That's when I added the RECV_EXTRA block to my _checkIncoming()..
Not a problem you notice when sending, only receiving..

fun stuff.. ~q

I have over 20 years of network programming experience in C :slight_smile: I also played with the ESP8266 back in the day (2016 or so) when I discovered that by default, the WiFi speed was very slow (something less than 300 kbps). By tweaking the MTU I managed to get it at 2-3MB/s.
Since then, things have changed and WiFi works pretty well, but I don't have that much experience with Arduino (I mean, I can do the basic things, but I am not that good at Arduino specific details).

It doesn't help that the Arduino documentation is VERY poor. On the official site, the WiFiclient won't even mention that you can read/write multiple bytes at once. You have to look on the source code to see that...

#include <WiFi.h>

const char *ssid = "your-SSID";
const char *password = "your-PASSWORD";
const char *host = "example.com";
const int port = 80;

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

  // Use WiFiClient to connect to a remote server
  WiFiClient client;
  if (client.connect(host, port)) {
    Serial.println("Connected to server");

    // Send data to the server
    client.write("Hello, server!");

    // Read multiple bytes from the server
    char buffer[256];
    int bytesRead = client.readBytes(buffer, sizeof(buffer));
    
    // Process the received data
    if (bytesRead > 0) {
      Serial.print("Received data: ");
      Serial.write(buffer, bytesRead);
    } else {
      Serial.println("No data received");
    }

    // Close the connection
    client.stop();
  } else {
    Serial.println("Connection to server failed");
  }
}

void loop() {
  // Your code here
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.