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?
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
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
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.
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.
thank you very very much.
Is there some kind of "going_above_and_beyond_duty-badge" ?
you should be honored with this badge
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
}
}
}
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?
@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).