ESP32 simple TCP-Democode Windows 10 telnet-TCP-connection closes instantly

Hi everybody,

I'm not sure if this problem is caused by the ESP8266-code or my windows 10 computer

I compiled and uploaded this code to a ESP8266 nodeMCU-baord

/*
 * Copyright (c) 2018, circuits4you.com
 * All rights reserved.
 * Create a TCP Server on ESP8266 NodeMCU. 
 * TCP Socket Server Send Receive Demo
*/
// https://circuits4you.com/2018/11/26/esp8266-nodemcu-tcp-socket-server-arduino-example/

#include <ESP8266WiFi.h>
//ESP32 #include <WiFi.h>


#define SendKey 0  //Button to send data Flash BTN on NodeMCU

int port = 8888;  //Port number
WiFiServer server(port);

//Server connect to WiFi Network
const char *ssid = "FRITZ!Box 7490";  //Enter your wifi SSID
const char *password = "";  //Enter your wifi Password

int count=0;
//=======================================================================
//                    Power on setup
//=======================================================================
void setup() 
{
  Serial.begin(115200);
  pinMode(SendKey,INPUT_PULLUP);  //Btn to send data
  Serial.println();

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password); //Connect to wifi
 
  // Wait for connection  
  Serial.println("Connecting to Wifi");
  while (WiFi.status() != WL_CONNECTED) {   
    delay(500);
    Serial.print(".");
    delay(500);
  }

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);

  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  
  server.begin();
  Serial.print("Open Telnet and connect to IP:");
  Serial.print(WiFi.localIP());
  Serial.print(" on port ");
  Serial.println(port);
}
//=======================================================================
//                    Loop
//=======================================================================

void loop() 
{
  WiFiClient client = server.available();
  
  if (client) {
    if(client.connected())
    {
      Serial.println("Client Connected");
    }
    
    while(client.connected()){      
      while(client.available()>0){
        // read data from the connected client
        Serial.write(client.read()); 
      }
      //Send Data to connected client
      while(Serial.available()>0)
      {
        client.write(Serial.read());
      }
    }
    client.stop();
    Serial.println("Client disconnected");    
  }
}
//=======================================================================

Then I start telnet on my windows 10 computer
Windowskey-R
CMD
telnet 192.168.178.46 8888

and get this result in the serial monitor

15:02:56.480 -> Connected to FRITZ!Box 7490
15:02:56.480 -> IP address: 192.168.178.46
15:02:56.480 -> Open Telnet and connect to IP:192.168.178.46 on port 8888
15:03:45.099 -> Client Connected
15:03:45.099 -> Client disconnected

as you can see by the timestamps the connection is instantly closed again.
Now what is causing this?
Does anybody have a different demo-code?
Does somebody know If I have to change something in the telnet-command or to configure telnet in a certain way to make it work?

best regards Stefan

Telnet is entirely unencrypted (the protocol was designed a long time ago, before the TCP/IP protocol suite was standardised) and your login ids, passwords, commands etc are in plain text, so easy to listen to. I would not be surprised that by default it's not accepting connections because it's soooo insecure.

You might need to activate telnet (sending from a phone #96*7* maybe ??) on your FRITZ!Box

Hi J-M-L,

thank you for answering. I used a second computer and on this second computer running windows 10 too I was able to establish the connection between microsoft telnet and the ESP8266.

I did see the received characters that I typed into telnet printed in the serial monitor. So the demo-code works.

Now next step is to send/receive characters over a TCP-connection between two ESP-boards.
But here I'm completely lost.

I have looked through So ALL democodes delivered by the ESP8266Wifi.h and Wifi.h and mutliple other online-tutorials

I want to emphasise: I want to learn it on the tiniest, smallest, possible demo-code.
So ALL democodes delivered by the ESP8266Wifi.h and Wifi.h

drop out

because they immitiately use http and this totally confuses me
This is the reason why I want to

not

tinker around with these tcp-http-examples

So if you happen to have a non-http-code or a link that demonstrates how to use tcp clients/servers that is what I'm looking for

best regards Stefan

your server sketch closes the connection immediately and destroys the client object.
see the WiFiTelnetToSerial example how it handles clients

This enables the telnet server of the fritzbox. This is only needed for very special configurations.
The fritzbox doesn't block the telnet protokoll in general.

it seemed to me @StefanL38 was trying to telnet to the fritzbox actually

typed here, untested as I don't have ESPs readily available at the moment

tcp_server.ino:

#ifdef ESP32
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif

const char* ssid     = "ESP32-AP";
const uint16_t portNumber = 50000; // System Ports 0-1023, User Ports 1024-49151, dynamic and/or Private Ports 49152-65535

WiFiServer server(portNumber);
WiFiClient client;
bool connected = false;

void setup() {
  Serial.begin(115200); Serial.println();
  Serial.print("Setting AP (Access Point)…");
  WiFi.softAP(ssid);

  IPAddress IP = WiFi.softAPIP();
  Serial.print(" -> IP address: "); Serial.println(IP);
  server.begin();
}

void loop() {

  if (!connected) {
    // listen for incoming clients
    client = server.available();
    if (client) {
      Serial.println("Got a client !");
      if (client.connected()) {
        Serial.println("and it's connected!");
        connected = true;
      } else {
        Serial.println("but it's not connected!");
        client.stop();  // close the connection:
      }
    }
  } else {
    if (client.connected()) {
      while (client.available()) Serial.write(client.read());
      while (Serial.available()) {
        char r = Serial.read();
        Serial.write(r); // local echo
        client.write(r);
      }
    } else {
      Serial.println("Client is gone");
      client.stop();  // close the connection:
      connected = false;
    }
  }
}

tcp_client.ino:

#ifdef ESP32
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif

const char* ssid     = "ESP32-AP";
const uint16_t portNumber = 50000; // System Ports 0-1023, User Ports 1024-49151, dynamic and/or Private Ports 49152-65535

IPAddress serverIP;
WiFiClient client;
bool connected = false;

void setup() {
  Serial.begin(115200); Serial.println();

  Serial.print("Connecting to SSID:"); Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  WiFi.begin(ssid);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.write('.');
  }
  Serial.println(".\nConnected");
  Serial.print("Local IP = "); Serial.println(WiFi.localIP());
  serverIP = WiFi.gatewayIP();
  Serial.flush();
}

void loop() {
  if (! connected) {
    if (client.connect(serverIP, portNumber)) {
      Serial.print("Connected to Gateway IP = "); Serial.println(serverIP);
      connected = true;
    } else {
      Serial.print("Could NOT connect to Gateway IP = "); Serial.println(serverIP);
      delay(500);
    }
  } else {
    while (client.available()) Serial.write(client.read());
    while (Serial.available()) {
      char r = Serial.read();
      Serial.write(r); // local echo
      client.write(r);
    }
  }
}

If I did not do stupid stuff, this should compile.

  • upload codes to your ESPs (8266 or 32)

  • Open a terminal window (I use CoolTerm, but PuTTY and the likes would do) at 115200 bauds and connect to the server's ESP serial port

  • reboot the server ESP just to be sure all is OK

  • Open a new terminal window, at 115200 bauds and connect to the client's ESP serial port

  • reboot the client ESP just to be sure all is OK

The server is configured in soft access point mode, so it creates its own WiFi
The client ESP should try to join the server WiFi network
Then, Once they are connected, whatever you type in the terminal on one side should appear on the other side

it's not very robust, if you unplug the client, the server won't know.

the code should be self explanatory, the server awaits a connection on portNumber 50000, which the client connects to. Then once they are connected, the Serial line is monitored and whatever is received there is sent to the client.

PS/ in the client you might also want to check if the client is still connected before sending the data and if not change the connected bool status. that would make it a bit more robust.

2 Likes

Hi J-M-L,

thank you very very much.
Is there some kind of "going_above_and_beyond_duty-badge" ?

you should be honored with this badge :ok_hand: :clap:

I have made small modifications to your code and added a lot of comments.
About some of the comments some experienced users will think
"oh man this is obvious" well if it is really obvious depends on the knowledge
And some of the comments explain things left and right on the fly
which will answer additional questions.

I added more serial output that - in case something is wrong - makes it easier to find the bug (wrong portnumber etc.)

From this point I can start to modify it to use the serial-input-basics receiver-functions for receiving with start / endmarker connection still alive-checking etc.

Demo-code showing send / receive characters over TCP

tcp_server-003.ino

#ifdef ESP32              // depending on the microcontroller-type 
#include <WiFi.h>         // include the right library for ESP32
#elif defined(ESP8266)
#include <ESP8266WiFi.h>  // or ESP8266
#endif

// this tcp_server demo-code creates its own WiFi-network 
// where the tcp_client demo-code connects to
// the ssid and the portNumber must be the same to make it work

const char* ssid     = "ESP32-AP";
const uint16_t portNumber = 50000; // System Ports 0-1023, User Ports 1024-49151, dynamic and/or Private Ports 49152-65535

WiFiServer server(portNumber);
WiFiClient client;
bool connected = false;

void setup() {
  Serial.begin(115200);
  Serial.println( F("Setup-Start") );
  Serial.print("Creating AP (Access Point) with name#");
  Serial.print(ssid);
  Serial.println("#");
  WiFi.softAP(ssid);

  IPAddress IP = WiFi.softAPIP();
  Serial.print(" -> softAP with IP address: ");
  Serial.println(IP);
  server.begin();
  Serial.print("TCP-Server on port ");
  Serial.print(portNumber);
  Serial.print(" started");
}

void loop() {

  char TCP_Char;
  char serialChar;
  
  if (!connected) {
    // listen for incoming clients
    client = server.available();
    if (client) {
      Serial.println("\n Got a client connected to my WiFi !");
      if (client.connected()) {
        Serial.println("an now this client has connected over TCP!");
        Serial.println("if client sends characters");
        Serial.println("they were printed to the serial monitor");
        connected = true;
      } else {
        Serial.println("but it's not connected over TCP!");        
        client.stop();  // close the connection:
      }
    }
  } 
  else {
    if (client.connected()) {
      
      // if characters sended from client is in the buffer
      while ( client.available() ) { 
        TCP_Char = client.read(); // take one character out of the TCP-receive-buffer
        Serial.write(TCP_Char);   // print it to the serial monitor
      }  

      // if characters have been typed into the serial monitor  
      while (Serial.available()) {
        char serialChar = Serial.read(); // take character out of the serial buffer
        Serial.write(serialChar); // print local echo
        client.write(serialChar); // send character over TCP to client
      }
    } 
    else {
      Serial.println("Client has disconnected the TCP-connection");
      client.stop();  // close the connection:
      connected = false;
    }
  }
}

tcp_client-003.ino

#ifdef ESP32               // depending on the microcontroller-type 
#include <WiFi.h>          // include the right library for ESP32
#elif defined(ESP8266)
#include <ESP8266WiFi.h>   // or ESP8266
#endif

// to this democode of the tcp_client belongs a tcp_server code
// which is configured as soft-accesspoint which creates its own
// WiFi-network the SSID of this WiFi-network must match the ssid defined here
const char* ssid     = "ESP32-AP";
const uint16_t portNumber = 50000; // System Ports 0-1023, User Ports 1024-49151, dynamic and/or Private Ports 49152-65535

IPAddress serverIP;
WiFiClient client;
bool connected = false;

void setup() {
  Serial.begin(115200);
  Serial.println( F("Setup-Start") );

  Serial.print("Connecting to SSID:");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  WiFi.begin(ssid);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.write('.');
  }
  Serial.println(".\nConnected");
  Serial.print("Local IP = ");
  Serial.println(WiFi.localIP());
  // the partner (the server) is configured as AccessPoint
  // to make it easy to obtain the IP-Adress through function WiFi.gatewayIP()
  serverIP = WiFi.gatewayIP();
  Serial.flush();
}


void loop() {
  char TCP_Char;
  char serialChar;

  if (! connected) {
    if (client.connect(serverIP, portNumber)) {
      Serial.print("Connected to server IP = ");
      Serial.println(serverIP);
      Serial.println("Now I'm listening for incoming characters...");
      connected = true;
    }
    else {
      Serial.print("Could NOT connect to server IP = ");
      Serial.println(serverIP);
      delay(500);
    }
  }
  else { // connected

    // if there are characters in the TCP-receive-buffer
    while (client.available()) {
      TCP_Char = client.read(); // take character out of TCP-receive-buffer
      Serial.write(TCP_Char);   // print it to the serial monitor
    }
    // if there are characters in the serial-receive-buffer
    while (Serial.available()) {
      serialChar = Serial.read(); // take character out of serial-receive-buffer
      Serial.write(serialChar);   // print local echo
      client.write(serialChar);   // send character over TCP to server
    }
  }
}

best regards Stefan

I have another question:

To establish the connection it is enough to have one ESP-microcontroller acting as the TCP-server.
To make the code more symmetric would it be a problem if on both ESPs the server is created and started?

best regards Stefan

Thanks for the kind words. Glad the code worked for you.

Good comments in the code (you might want to check spelling / grammar to improve it further).

You can have symmetric code where the ESP offers a service (listens on a specific port) and connects as a client to another ESP's service port.

@J-M-L
A million thank yous for posting that code. I've slightly modified it for my own use but it's working and I understand it well enough to use it and adapt it for what I need. Like @StefanL38 I'd been looking for something like this for ages.

@StefanL38
Thank you for asking the question that got this answer.

@J-M-L @StefanL38 @Juraj
I don't suppose any of you would like to make a proper tutorial out of this by any chance? (Feel free to decline if you don't want to).

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