Hallo,
ich sende Daten an einen Webserver und empfange die Rückgabe des Servers. Dabei will ich nur Strings zwischen < und > ausgeben, alles andere soll übersprungen werden.
Ich habe mir jetzt folgende Funktion geschrieben bin mir aber nicht sicher ob das so in Ordnung ist da doch einige while Schleifen drin vorkommen.
Funktionieren tut sie auf jeden Fall.
static const int BUFSIZE=20;
static char clientResponseStr[BUFSIZE];
//Für Serial.read und Client.read zum auslesen bestimmter Werte
const char startOfNumberDelimiter = '<';
const char endOfNumberDelimiter = '>';
void getServerResponse()
{
if(connected)
{
int pos=0;
while (client.connected())
{
c = client.read();
while(c != startOfNumberDelimiter) // so lange einlesen bis StartDelimiter empfangen wird
{
c = client.read();
}
while (client.available())
{
c = client.read();
if(c == endOfNumberDelimiter) break;
clientResponseStr[pos++] = c;
}
clientResponseStr[pos]=0; // EndeKennung
Serial.println(clientResponseStr);
Serial.println("Verbindung geschlossen.");
Serial.println();
client.stop();
connected = false;
} // while (client.connected())
} // if(connected)
}
Hat eventuell jemand einen Tipp ob das so in Ordnung ist oder ob es eine bessere Möglichkeit dafür gibt?
Vielen Dank
Aus meiner Sicht schon sehr effektiv gelöst, da Du keinen zusätzlichen Speicher verbrauchst, weil nur die relevanten Daten gespeichert werden. Zusätzlich wird der nicht unwichtige Sonderfall "es wird kein Start-Zeichen gefunden" auch mit abgedeckt, da die '\0' Terminierung außerhalb der Lese-Schleife gemacht wird. Damit kommt ein leerer String raus, wenn das Start-Zeichen fehlt.
Ich würde aber noch den Fall abfangen, das mehr Zeichen gesendet werden als der Puffer fassen kann:
if(c == endOfNumberDelimiter || pos == (BUFSIZE -1)) break;
In diesem Fall wird dann die letztmögliche Position im Puffer mit der '\0'-Terminierung geschrieben und Du ahst wieder einen validen String.
Willst Du den Fall "Rückgabe zu lang" gesondert behandeln, brauchst Du dafür einen eigenen Vergleich der ggf. ein Fehler-Flag setzt.
Mario.
Oh vielen Dank mkl0815 für den Tipp mit dem leeren String. Das habe ich gar nicht bedacht.
Außerdem habe ich hier noch etwas geändert
while (client.available())
zu
while (client.available() && pos < (BUFSIZE-1))
Das sollte doch auch noch etwas bringen da die buffergröße vorher nicht berücksichtigt wurde.
while(c != startOfNumberDelimiter) // so lange einlesen bis StartDelimiter empfangen wird
{
c = client.read();
}
setzt natürlich voraus, dass überhaupt ein '<' kommt. Wenn nicht, braucht der Arduino ein reset ...
michael_x Du hast Recht, er kommt dann aus der Schleife nicht raus.
Hat auch jemand einen Tipp wie ich das vermeiden kann?
Vielleicht so :
int pos = 0;
*clientResponseStr=0; // vorsorglich EndeKennung setzen
while(c != startOfNumberDelimiter) // so lange einlesen bis StartDelimiter empfangen wird
{
c = client.read();
if ( c == -1) return; // Abbruch, falls Eingabe unerwartet endet
}
Natürlich ungetestet ...
wieso braucht der Arduino dann einen Reset?
Habe es gerade getestet. Du hast Recht.
Glückwunsch, testen ist schwerer als programmieren.
Das "wieso" sollte dir aber klar sein, da du selbst bemerkst hast, dass "da doch einige while Schleifen drin vorkommen".
Ja ich weiß, ich habe meinen letzten Beitrag auch gleich bearbeitet. Habe gehofft dass ihn eh noch keiner gelesen hat. Sorry
Zu Deinem Beispiel von eben. Einfach perfekt. Es funktioniert super.
Vielen Dank michael_x!