Search code examples
tcparduinoesp8266esp32arduino-esp8266

ESP32: Send a simple TCP Message and receive the response


I want to do the same request as with the netcat "nc" command on my computer with an ESP32:

Computer:

$ nc tcpbin.com 4242
Test
Test

What I've tried so far:

Create a wifi client and listen to an answer:

  • Connect to a tcp server
  • write a message
  • wait and read the answer
#include <Arduino.h>
#include <WiFi.h>

WiFiClient localClient;

const char* ssid = "...";
const char* password = "...";

const uint port = 4242;
const char* ip = "45.79.112.203"; // tcpbin.com's ip


void setup() {
  Serial.begin(115200);
  Serial.println("Connect Wlan");
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(WiFi.localIP());
}

void loop() {
  sendRequest();
  delay(200);
}

void sendRequest() {
  if(!localClient.connected()) {
    if (localClient.connect(ip, port)) {
      Serial.println("localClient connected");
      localClient.write('A'); //Single char
      Serial.println("msg sent");
    }
  }

  if(localClient.connected()) {
    Serial.println("Start reading");
    if (localClient.available() > 0) {
      char c = localClient.read();
      Serial.print(c);
    }
    Serial.println("Stop reading");
  }
  
}

I'm pretty sure that I misunderstood something of the tcp concept during the implementation. However, after various approaches and trying other code snippets, I can't come up with a solution.

thank you in advance

regards Leon


Solution

  • There are several issues with your code.

    If you test nc, you will notice that the server will not acknowledge back until your press 'return'. You are sending a single byte without termination in your code, so the server is waiting for subsequent data. To terminate the data, you need to send a '\n', or instead of using client.write('A'), use client.println('A').

    A network response take time, your current code expecting immediate response without waiting with if (localClient.available() > 0).

    Here is the code that will work:

    void sendRequest() {
    
      if (localClient.connect(ip, port)) {                 // Establish a connection
    
          if (localClient.connected()) {
            localClient.println('A');                      // send data
            Serial.println("[Tx] A");
          }
    
          while (!localClient.available());                // wait for response
          
          String str = localClient.readStringUntil('\n');  // read entire response
          Serial.print("[Rx] ");
          Serial.println(str);
     
      }
      
    }