ESP32 - Client lässt sich nicht mit Webserver connecten

Hallo,

ich nutze die WiFiClient Klasse und deren connect Methode zum Verbinden beim Server.
Be deri WiFiServer-Bib funktioniert sie, bei der WebServer-Bib, die ich brauche, nicht.

Ich kann es mir nicht gant erklären, da WiFiClient immer gleich bleibt.
Der Client soll sich mit der ServerIP und ServerPort beim Server verbinden und dann seine IP-Adresse an den Server schicken.
Da kommt dann immer die Ausgabe connection failed.

    if (!client.connect(host, port)) {
        Serial.println("connection failed");
        return;
    }

Hier mal ein Beispiel Code:
Server (auskommentiert steht für WiFiServer).

#include <WiFi.h>
#include <WebServer.h>
const char* ssid     = "xxxxxx";
const char* password = "xxxxxx";
/* create a server and listen on port 8088 */
//WiFiServer server(8088);
WebServer server(8088);
void setup()
{
    Serial.begin(115200);
    Serial.print("Connecting to ");
    Serial.println(ssid);
    /* connecting to WiFi */
    WiFi.begin(ssid, password);
    /*wait until ESP32 connect to WiFi*/
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected with IP address: ");
    Serial.println(WiFi.localIP());
    /* start Server */
    server.begin();
}
void loop(){
    /* listen for client */
   // WiFiClient client = server.available();  //WiFiServer
    WiFiClient client = server.client();
    uint8_t data[30]; 
    if (client) {                   
      Serial.println("new client");         
      /* check client is connected */           
      while (client.connected()) {          
          if (client.available()) {
              int len = client.read(data, 30);
              if(len < 30){
                  data[len] = '\0';  
              }else {
                  data[30] = '\0';
              }    
              Serial.print("client sent: ");            
              Serial.println((char *)data); 
          }
      } 
    }
}

Client: (bei beiden Bibs gleich)

#include <WiFi.h>
/* change ssid and password according to yours WiFi*/
const char* ssid     = "xxxxxx";
const char* password = "xxxxxx";
/*
 * This is the IP address of your PC
 * [Wins: use ipconfig command, Linux: use ifconfig command]
*/
const char* host = "192.168.178.183";
const int port = 8088;
void setup()
{
    Serial.begin(115200);
    Serial.print("Connecting to ");
    Serial.println(ssid);
    /* connect to your WiFi */
    WiFi.begin(ssid, password);
    /* wait until ESP32 connect to WiFi*/
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected with IP address: ");
    Serial.println(WiFi.localIP());
}
void loop()
{
    delay(5000);
    Serial.print("connecting to ");
    Serial.println(host);
    /* Use WiFiClient class to create TCP connections */
    WiFiClient client;
    
    if (!client.connect(host, port)) {
        Serial.println("connection failed");
        return;
    }
    /* This will send the data to the server */
    client.print(WiFi.localIP());
    client.stop();
}

Danke für weiterführende Antworten.
mfg werdas34

werdas34:
Be deri WiFiServer-Bib funktioniert sie, bei der WebServer-Bib, die ich brauche, nicht.

Hallo werdas34,

welche Bibliotheken sind das genau? Es gibt da inzwischen mehrere.
Hast Du uns da einen Link?

Gruß, Jürgen

Hallo,
ich habe leider nicht ganz verstanden was Du letztlich vorhast. Mit Deinem Client sketch baust Du eine TCP Verbindung auf und sendest damit auch.

Auf der Server Seite benötigst Du dann also den WiFI Server. Das scheint ja auch zu klappen. Wenn Du jetzt allerdings den Webserver nutzen willst dann must Du auf der client Seite ein HTTP Protokoll absetzten.

Schau dir mal die Seite von werner.rothschopf an , ich glaube da macht er sowas.

Du kannst WebSever und WifiServer auch gleichzeitig nutzen. Webserver für die Anzeige von Webseiten , Daten von Sensoren mittels TCP empfangen.

Heinz

Katsumi_S:
Hallo werdas34,

welche Bibliotheken sind das genau? Es gibt da inzwischen mehrere.
Hast Du uns da einen Link?

Gruß, Jürgen

Ja klar.
WiFiClient.h:

WiFiServer.h:

WebServer.h:

Wie man auch sieht sind sie alle von espressif. Daher vermute ich mal stark, das sie untereiinander kompatibel sind.

Rentner:
Hallo,
ich habe leider nicht ganz verstanden was Du letztlich vorhast. Mit Deinem Client sketch baust Du eine TCP Verbindung auf und sendest damit auch.

Auf der Server Seite benötigst Du dann also den WiFI Server. Das scheint ja auch zu klappen. Wenn Du jetzt allerdings den Webserver nutzen willst dann must Du auf der client Seite ein HTTP Protokoll absetzten.

Schau dir mal die Seite von werner.rothschopf an , ich glaube da macht er sowas.

Du kannst WebSever und WifiServer auch gleichzeitig nutzen. Webserver für die Anzeige von Webseiten , Daten von Sensoren mittels TCP empfangen.

Heinz

Das war mir nicht klar, das einer nur für TCP und der andere nur für HTTP ist.
Dachte beide machen die selben Sachen und wollte jetzt nicht doppelt verwenden für nur eine Aufgabe. So macht das aber Sinn.

Vielen Dank.

Eine Frage noch:
Wenn ich per TCP die IP-Adresse vom Client an den (WiFi)Server schicke kommt das immer nur so bruchweise an?
Ich sende z.B. 192.168.723.145
Dann kommt meistens 192 an und erst im nächsten Schritt .168.723.145. Teilweise auch garnicht.
An der Länge von 30 kann es nicht liegen.
Woran liegt das? Wie behebe ich das?

mfg werdas34

Hallo,

dann schicke doch mal einen normalen text

client.print("das ist ein text");

Warum willst Du denn die IP senden, Du kannst doch die IP von dem der sendet auf der Empfänger Seite abfragen.

Serial.println(client.remoteIP());

Heinz

Hallo,

erstmal vielen Dank. Jetzt funktioniert alles.

Eine Frage noch:
Ich habe einen TCP Server (WifiServer) und mehrere Clients haben eine Verbindung aufgebaut.
Kann ich im Nachhinein irgendwie auf die Clients zugreifen? Oder muss ich mir das Client-Objekt seperat speichern?
Und wenn ich auf Serverseite die Client Verbindung kappen möchte - wie geht das?

WiFiServer server;
WiFiClient client;
server._discard(client);
// oder
WiFiServer._s_discard(serverTCP, client);

So kennt er oben die Methode nicht als Member an?
Und unten möchte er nen Variablennamen statt den Klassenamen.
Liegt das daran das die protected sind? Wie nutze ich diese?
Und laut der Doku brauche ich als Parameter ein ClientContext*. Wie komme ich von einem WiFiClient zu ClientContext?

mfg werdas34

Probier mal client.close() oder was meinst Du genauer?

Gruß Tommy

Hallo,
der Server kann eine Antwort senden. Damit könnte der client die Info bekommen das die Daten richtig verarbeitet worden sind. Nachträglich kann der Server meines Wissens keine Verbindung mehr zum Client aufnehmen. Macht ja auch keinen Sinn, dann währe der Client ja auch ein Server.

Heinz

Nachtrag den zweiten Teil Deiner Frage hab ich nicht verstanden.

Rentner:
Nachträglich kann der Server meines Wissens keine Verbindung mehr zum Client aufnehmen.

Doch, bei Websockets.

Gruß Tommy

Ich versuche meiinen Use Case zu erklären. Vielleicht wird es dann klarer.

Zwischen Client und Server herscht eine 1/0 zu n - Beziehung. D.h. Ein Server kann n beliebig viele Clients verwalten, Ein Client kann nur max. zu einem Server gehören.

Nun ist ein Client mit einem Server verbunden. Der Server braucht aus irgendwelchen Gründen den Client nicht mehr und kappt die Verbindung.
Jetzt könnte der Client eine Verbindung zu einem neuen Server aufnehmen, was vorher nicht möglich war.

Grobe Idee war es jetzt:
Client

if(!client.connected()){
  //Verbindung zu neuem TCP Server
}

Server:

//Option 1
server.discard(client);
//Option 2
//Server kann mehrere Clients verwalten. Also Client-Objekt seperat speichern.
client.close();

Oder habei ich gerade einen Denkfehler und übersehe was?

werdas34:
Ein Client kann nur max. zu einem Server gehören.

Jetzt könnte der Client eine Verbindung zu einem neuen Server aufnehmen, was vorher nicht möglich war.

Du widersprichst Dir selbst.

Gruß Tommy

Hallo,

schreib Doch mal was Du letztlich vorhast, eventuell bist Du ja mit deinem Konzept schon auf dem Holzweg und eine andere Struktur ist sinvoller.

Nachtrag
ich mache jetzt mal einen ganz einfachen Vergleich, nur zum Verständniss

Dein PC ist in Verbindung mit deinem Brauser ein Client. Der kann sich bei beliebig vielen Servern, Webseiten anmelden. ok. nicht bei 100 gleichzeitig , aber Du rufst eine Seite auf , die Verbindung wir aufgebaut , der Server antwortet , sendet die HTML seite, anschliessend wird in der Regel die Verbindung sofort wieder abgebaut. Wenn Du die Seite aktualisierst wird die Verbindung neu aufgebaut.

Ob das jetzt eine HTML Seite ist oder nur eine TCP Verbindung oder gar UDP ist doch egal.
@Tommy ich hoffe ich hab keinen Blödsinn erzählt :wink:

Heinz

Wenn wir mal so Kleinigkeiten wie Keep alive bei HTTP(S) und einiges bei TCP weg lassen, passt das schon. Diese haben für das dargelegte Problem aber erst mal keine Relevanz.

Ich glaube, der TO weiß es auch nicht so recht oder kann es nicht erklären.

Gruß Tommy

Rentner:
Dein PC ist in Verbindung mit deinem Brauser ein Client. Der kann sich bei beliebig vielen Servern, Webseiten anmelden. ok. nicht bei 100 gleichzeitig , aber Du rufst eine Seite auf , die Verbindung wir aufgebaut , der Server antwortet , sendet die HTML seite, anschliessend wird in der Regel die Verbindung sofort wieder abgebaut. Wenn Du die Seite aktualisierst wird die Verbindung neu aufgebaut.

Ob das jetzt eine HTML Seite ist oder nur eine TCP Verbindung oder gar UDP ist doch egal.

UDP solltest du aus deiner Erklärung streichen, da es eine verbindungslose Kommunikation ist.

Ja, UDP ist "fire and forget", das hatte ich überlesen.

Gruß Tommy

Hallo,
Ok UDP ist keine Verbindung in dem Sinne , dennoch kann ein Client sich mit unterschiedlichen mehreren Servern verbinden , etwas senden und eine Antwort bekommen , das war der Ausgangspunkt meiner Überlegung zum Post des TO

Heinz

Tommy56:
Du widersprichst Dir selbst.

Gruß Tommy

Zwischenzeitlich kappt der Server die Verbindung zum Client.

Nochmal etwas ausführlicher:
Client kann nur max. mit einem Server eine Verbindung eingehen.
Aus irgendwelchen Gründen braucht der Server den Client nun nicht mehr.
-> Server kappt die Verbindung.
-> Client braucht ein Feedback, das der Server nicht mehr seinen Dienst beansprucht.
-> Client stellt fest, das Server die Connection abgebrochen hat und macht sich wieder bereit wieder eine neue Verbindung zu Servern einzugehen.
-> Hat er eine neue Verbinung aufgebaut, kann er zu keinem anderem Server eine Verbindung aufbauen. Erst wenn der Server den Client wieder nicht mehr braucht.
-> Server kappt die Verbindung
-> ....

Also zu jedem Zeitpunkt hat der Client eine oder keine Verbindung zu einem Server aufgebaut.
Serverseitig kann der Dienst vom Client "entfernt" werden.
Sobald der Client das feststellt, soll er sich wieder für andere Server bereit halten.
Bei erfolgreicher Verbindung sperrt sich der Client für weitere Server.

mfg werdas34

werdas34:
Zwischenzeitlich kappt der Server die Verbindung zum Client.

Nochmal etwas ausführlicher:
Client kann nur max. mit einem Server eine Verbindung eingehen.
Aus irgendwelchen Gründen braucht der Server den Client nun nicht mehr.
-> Server kappt die Verbindung.
-> Client braucht ein Feedback, das der Server nicht mehr seinen Dienst beansprucht.
-> Client stellt fest, das Server die Connection abgebrochen hat und macht sich wieder bereit wieder eine neue Verbindung zu Servern einzugehen.
-> Hat er eine neue Verbinung aufgebaut, kann er zu keinem anderem Server eine Verbindung aufbauen. Erst wenn der Server den Client wieder nicht mehr braucht.
-> Server kappt die Verbindung
-> ....

Also zu jedem Zeitpunkt hat der Client eine oder keine Verbindung zu einem Server aufgebaut.
Serverseitig kann der Dienst vom Client "entfernt" werden.
Sobald der Client das feststellt, soll er sich wieder für andere Server bereit halten.
Bei erfolgreicher Verbindung sperrt sich der Client für weitere Server.

mfg werdas34

Client-Server-Modell

Das mit dem Feedback habe ich auch, unter anderem als Dorn im Auge.
Aber ich kann bei der WiFiClient den Status abfragen.

if(!client.connected()){
  // neuen Server suchen
}

Daher gehe mal davon aus, dass das als Feedback genügt.

Ich müsste nur serverseitig den Client rauswerfen. Nur da weiß ich noch nicht so genau wie das gehen soll.

mfg werdas34

Das hatte ich Dir in #6 bereits geschrieben. Der Server bearbeitet die Anfrage vom Client, antwortet entsprechend und beendet die Verbindung.
Der Server braucht den Client nicht. Der Client will was vom Server.
Irgendwie hast Du Client-Server immer noch nicht verstanden.

Gruß Tommy