mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ESP8266 - SPIFFS streamFile will nicht richtig auf Android aber auf PC


Autor: Timmo H. (masterfx)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich baue gerade ein Webinterface auf dem ESP und Teste es vorrangig 
erstmal auf dem PC via Chrome 67.0.3396.99 (aber auch auf Edge) und 
alles hat bisher gut funktioniert.
Dann wollte ich das Interface mal auf meinem Android Handy mit der 
neusten Chrome Version 68.0.3440.91 (war mit der alten aber auch so) und 
da laden die Seiten mit etwas größeren Bildern (> ~20 kB) nicht. Der 
Content liegt auf dem SPIFFS.
Also habe ich einfach mal nur das Bild geladen 
"http://192.168.0.120/test.jpg"; welches 80 kB groß ist. Unter Chrome auf 
PC dauert es rund 390ms bis es geladen ist (laut Chrome Devtools). Rufe 
ich die selbe Adresse auf dem Android Handy auf, läd er sich tot. Auf 
dem Terminal mache ich zudem noch eine Ausgabe welches File angefordert 
wurde " handleFileRead: xyz" und eine Ausgabe wenn es gesendet wurde 
"Sent file: xyz". Und auch auf dem Terminal sieht man dass das "Sent 
file: xyz" sehr viel später kommt als wenn man es über PC aufruft.

Ich benutze PlatformIO mit Espressif 8266 1.7.3.

Der Code ist überschaubar (siehe Anhang).
Der ESP verbindet sich mit meinem WLAN, der PC ist via RJ45 
angeschlossen und das Handy natürlich auch via WLAN am Router.

Jemand eine Idee woran das liegen kann?

: Bearbeitet durch User
Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde die Netzwerk-Kommunikation mit Wireshark untersuchen.

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibt es leider nicht für Android

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du sollst das Wireshark ja auch auf deinem PC laufen lassen.

Manche Router erlauben es, den Verkehr zwischen ESP und Smartphone 
mitschnüffeln. Bei manchen ist es einstellbar. Wenn du dieses Glück hast 
wäre das auf jeden Fall die einfachste Option.

Wenn dein Router das nicht erlaubt, kannst du den ESP mit der Ethernet 
Buchse deines PC verbinden und das Smartphone mit der WLAN 
Schnittstelle. Dann ist dein PC der Router zwischen dieses beiden 
Geräten und dann kann der auch den ganzen Netzwerkverkehr mitlesen.

Dazu gibt es Tutorials im Netz.

Außerdem gibt es Alternativen zu Wireshark, die auf Android laufen: 
https://techwiser.com/wireshark-alternatives-for-android/ Ich würde mein 
Smartphone allerdings nicht rooten.

: Bearbeitet durch User
Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> kannst du den ESP mit der Ethernet
> Buchse deines PC verbinden
Cool, wie geht das? Der ESP hat nur WLAN...
Selbst wenn ich meinem PC via WLAN mit dem Router verbinde geht es ja 
auch problemlos. Ich könnte meinen PC natürlich zum AP machen aber das 
ist mir ehrlich gesagt alles zu viel Aufwand. Ich vermute einfach einen 
Bug im ESP-Core oder so. Ich werde dann mal weiter googeln. Irgendwas 
scheint das Handy halt anders zu machen als der PC

: Bearbeitet durch User
Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Cool, wie geht das? Der ESP hat nur WLAN...
Denk nach! Natürlich mit einer WLAN Brücke oder einem WLAN Router.

> Ich könnte meinen PC natürlich zum AP machen
Auch das wäre eine Möglichkeit. Vielleicht sogar die bessere weil du 
dann keine zusätzliche Hardware bnenötigst.

> Ich vermute einfach einen Bug im ESP-Core oder so.
Vermuten nützt leider nichts, Wissen auch nicht. Du brauchst einen 
Workaround - sofern der Fehler nicht in deinem eigenen Code steckt.

> Irgendwas scheint das Handy halt anders zu machen als der PC
Eben das ist der spannende Punkt. Mit einem Netzwerk Trace findest du 
den Knackpunkt (vielleicht) und dann kannst um den herum bauen.

Mir ist gerade noch eine Lösung eingefallen: Du kannst Android x86 als 
virtuelle Maschine auf deinem PC laufen lassen. Falls der Fehler darin 
nicht auftritt, kannst du das Google SDK herunterladen, da ist ein 
Android ARM Emulator drin.

: Bearbeitet durch User
Autor: Sascha W. (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Timmo,

du solltest auf den Async Webserver wechseln, der einfache Server hat 
ein Problem wenn man mehrere Seiten gleichzeitig anfragt.
Und da der Browser gern mal noch das Favicon laden will hängt das Teil 
dann.

Sascha

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sascha,
danke für den Hinweis. Dennoch frage ich mich warum es dann auf dem PC 
einwandfrei funktioniert, auch wenn die Seite mehrere Bilder enthält.
Ich meine selbst wenn ich als Adresse nur das jpg oder bmp angebe... 
dann lädt er ja nichts anderes parallel. Gucke ich mir die http header 
mal an passiert da auch nicht wirklich mehr als es müsste
GET /test.bmp HTTP/1.1
Host: 192.168.0.120
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7

HTTP/1.1 200 OK
Content-Type: image/bmp
Content-Length: 90054
Connection: close

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mhh, habe gerade noch mal die Size ausgeben lassen.
bool handleFileRead(String path) { // send the right file to the client (if it exists)
  Serial.println("handleFileRead: " + path);
  if (path.endsWith("/")) path += "index.html";          // If a folder is requested, send the index file
  String contentType = getContentType(path);             // Get the MIME type
  String pathWithGz = path + ".gz";
  if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { // If the file exists, either as a compressed archive, or normal
    if (SPIFFS.exists(pathWithGz))                         // If there's a compressed version available
      path += ".gz";                                         // Use the compressed verion
    File file = SPIFFS.open(path, "r");                    // Open the file
    size_t sent = server.streamFile(file, contentType);    // Send it to the client
    file.close();                                          // Close the file again
    Serial.println(String("\tSent file: ") + path);
    Serial.println(String("\tSent size: ") + sent);
    return true;
    
  }
  Serial.println(String("\tFile Not Found: ") + path);   // If the file doesn't exist, return false
  return false;
}
Wenn ich das bmp von PC lade:
handleFileRead: /test.bmp
        Sent file: /test.bmp
        Sent size: 90054
Vom Handy (dauert aber ewig)
handleFileRead: /test.bmp
        Sent file: /test.bmp
        Sent size: 2920
Komisch, 2920 ist genau 2x 1460 (MTU)

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay nach weiterem Googlen scheint es ein Bug zu sein.
Jedoch funzt suggerierte Lösung nicht
    int size = file.size();
    
    char buf[1024];
    while(size > 0) {
      size_t len = std::min((int)(sizeof(buf) - 1), size);
      file.read((uint8_t *)buf, len);
      server.client().write((const char*)buf, len);
      size -= len;
    }
bei mir nicht.

Autor: Stefanus F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich schätze du hast die aktuelle Plugin Version 2.4.2 verwendet. 
Versuche es mal mit der älteren 2.3.0.

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tatsache mit 2.3.0 gehts. Dauert zwar ca. 10x so lang, aber es geht... 
"Danke"

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In selbst geschriebenen Client Anwendungen (auch Apps) kannst du die 
Socket-Option TCP_NODELAY beim Verbindungsaufbau setzen. Dann läuft die 
Übertragung schneller.

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessant.
2.3.0:  return _currentClient.write(file, HTTP_DOWNLOAD_UNIT_SIZE);
2.4.1:  return _currentClient.write(file);

Wobei die HTTP_DOWNLOAD_UNIT_SIZE = 1460 ist. Warum haben die das raus 
genommen? Klar scheint schneller zu sein wenn die MTU größer ist, aber 
wenns nicht immer geht ist halt auch nervig

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.