Hallo zusammen,
Mein Code soll einen ADXL345-FIFO(32 Stufen) durch MQTT von meinem
ESP32-Board an den PC senden.
Um die gesendeten Pakete zu überwachen, verwende ich Wireshark. Wenn ich
Zeile 127 bzw. 128 kommentiere , wird mein Paket fragmentiert und ich
sehe Pakete von 1490 Byte und 235 Byte, obwohl meine tatsächliche
Paketgröße (msg) 860 Byte beträgt. Außerdem zeigt wire shark nur die
publish messages und benachrichtigt dass die connect command fehlt(aber
ich sehe die Sensor Daten).
Wenn ich Zeile 127 "client.disconnect();" bzw. 128 "delay(1000);" in dem
Code nehme, ist alles in Ordnung und in Wireshark sehe ich die 860 Bytes
so, wie es sein soll. Außerdem kann ich dann ein Connect command und
alle ACK und ein Disconnect command sehen. Die 2 Lösungen mit disconnect
und das Delay will ich nicht machen damit die Verbindung sich nicht
verlangsamt.
Kann mir bitte jemand sagen, warum ich 1490 Bytes sehe, obwohl ich nur
860 Bytes sende?
Hier ist mein Code:
Hammad S. schrieb:> Hier ist mein Code:
Wer soll diesen Kram lesen?
> Kann mir bitte jemand sagen, warum ich 1490 Bytes sehe,
Du benutzt nicht ernsthaft Wireshark, siehst ein Paket mit 1490 Bytes,
und schaust nicht hinein, wie es aufgebaut ist?
Ernsthaft?
Einer schrieb:> Hammad S. schrieb:>> Hier ist mein Code:>> Wer soll diesen Kram lesen?
der helfen will vielleicht :D?
>>> Kann mir bitte jemand sagen, warum ich 1490 Bytes sehe,>> Du benutzt nicht ernsthaft Wireshark, siehst ein Paket mit 1490 Bytes,> und schaust nicht hinein, wie es aufgebaut ist?>> Ernsthaft?
Ja ernsthaft. Was denkst du dir? Wieso gibt es Forums auf der Welt?
Man stellt nur eine Frage wenn man die Antwort davon nicht weiß. Also
entweder seist du nett und du antwortest die Frage wenn du die Antwort
schon kannst oder du reagierst gar nicht darauf :)
Hammad S. schrieb:> Ja ernsthaft. Was denkst du dir? Wieso gibt es Forums auf der Welt?> Man stellt nur eine Frage wenn man die Antwort davon nicht weiß.
Du guckst also mit Wireshark, siehst dort etwas, was Deiner Meinung nach
seltsam ist - und stellst dann Deine Frage, ohne uns überhaupt zu
zeigen, worum es genau geht.
Lade doch mal PCAP-Files hoch.
Hmmm schrieb:> Hammad S. schrieb:>> Ja ernsthaft. Was denkst du dir? Wieso gibt es Forums auf der Welt?>> Man stellt nur eine Frage wenn man die Antwort davon nicht weiß.>> Du guckst also mit Wireshark, siehst dort etwas, was Deiner Meinung nach> seltsam ist - und stellst dann Deine Frage, ohne uns überhaupt zu> zeigen, worum es genau geht.>> Lade doch mal PCAP-Files hoch.
habe die hochgeladen
In SPI_MQTT_ohne_disconnect.pcapng sieht man es gleich beim ersten
Paket:
Da kommen erst Dein MQTT-Publish, dahinter folgt aber plötzlich noch ein
zweiter Datensatz. Siehe beigefügter Screenshot, der markierte Bereich
ist die eigentliche Publish-Message, der Rest gehört dort nicht hin.
Hammad S. schrieb:> Wenn ich> Zeile 127 bzw. 128 kommentiere , wird mein Paket fragmentiert
In Zeile 127 wird der Buffer geleert. Wenn das nicht passiert, ist die
nächste Nachricht halt grösser und wird deshalb fragmentiert.
Hmmm schrieb:> In SPI_MQTT_ohne_disconnect.pcapng sieht man es gleich beim ersten> Paket:>> Da kommen erst Dein MQTT-Publish, dahinter folgt aber plötzlich noch ein> zweiter Datensatz. Siehe beigefügter Screenshot, der markierte Bereich> ist die eigentliche Publish-Message, der Rest gehört dort nicht hin.
ja das ist genau mein Problem
> Hammad S. schrieb:>> Wenn ich>> Zeile 127 bzw. 128 kommentiere , wird mein Paket fragmentiert>> In Zeile 127 wird der Buffer geleert. Wenn das nicht passiert, ist die> nächste Nachricht halt grösser und wird deshalb fragmentiert.
damit das nicht auftritt leere ich den String( data=""; ) dierekt nach
dem publish aber anscheinend wird es komischer Weise nicht geleert.
Hallo,
wenn ich nicht irre war 1490Byte die Puffergröße des TCP-Stack beim
ESP8266/ESP32.
Wenn weniger Daten gesendet werden schickt er das Paket nach einem
internen Timeout raus, wenn es mehr ist fragmentiert er auf die
Puffergöße.
Allerdings habe ich das bisher nur mal nachgeschaut weil das Holen eines
jpg aus dem SPIFFS mal schnell ging und mal "ewig" dauerte. Ich habe
damals die Schleife etwas angepasst damit sich die Zugriffe nicht
gegenseitig ausgebremst haben. Bei MQTT hatte ich noch keinen Grund,
darüber nachzudenken.
Gruß aus Berlin
Michael
Hammad S. schrieb:> Wenn ich Zeile 127 "client.disconnect();" bzw. 128 "delay(1000);" in dem> Code nehme, ist alles in Ordnung
Du verstehst einen grundlegenden Punkt von TCP falsch: Im Gegensatz zu
UDP hast Du keinen Einfluss darauf, wie der TCP-Stack die gesendeten
Daten in Pakete verpackt.
Wenn Du sie schnell hintereinander sendest, kann es also durchaus
passieren, dass sie zu einem Paket zusammengefasst werden - im Idealfall
so, dass die Path MTU ausgereizt wird und somit der geringste Overhead
entsteht.
Wenn Du die Verbindung zwischendurch trennst oder einen Moment wartest,
hebelst Du dieses Verhalten aus.
Hmmm schrieb:> Du verstehst einen grundlegenden Punkt von TCP falsch: Im Gegensatz zu> UDP hast Du keinen Einfluss darauf, wie der TCP-Stack die gesendeten> Daten in Pakete verpackt.
Dazu kommt, dass jede Netzwerk-Komponente (z.B. Router) die Stückelung
des TCP Datenstroms ändern darf.
Es gibt immer wieder Produkte, die wegen Missachtung dieses Fakts
Probleme machen. Das war schon vor 30 Jahren so, und heute immer noch.
Michael U. schrieb:> Hallo,>> wenn ich nicht irre war 1490Byte die Puffergröße des TCP-Stack beim> ESP8266/ESP32.
ja genau
> Wenn weniger Daten gesendet werden schickt er das Paket nach einem> internen Timeout raus, wenn es mehr ist fragmentiert er auf die> Puffergöße.> Allerdings habe ich das bisher nur mal nachgeschaut weil das Holen eines> jpg aus dem SPIFFS mal schnell ging und mal "ewig" dauerte. Ich habe> damals die Schleife etwas angepasst damit sich die Zugriffe nicht> gegenseitig ausgebremst haben.
wie hast du genau die Schleife angepasst?
Bei MQTT hatte ich noch keinen Grund,
> darüber nachzudenken.>> Gruß aus Berlin> Michael
Hmmm schrieb:> Hammad S. schrieb:>> Wenn ich Zeile 127 "client.disconnect();" bzw. 128 "delay(1000);" in dem>> Code nehme, ist alles in Ordnung>> Du verstehst einen grundlegenden Punkt von TCP falsch: Im Gegensatz zu> UDP hast Du keinen Einfluss darauf, wie der TCP-Stack die gesendeten> Daten in Pakete verpackt.
Vielen Dank für die Erklärung. Ich habe darauf geachtet, dass meine
Pakete wegen die MTUs die 1500 Bytes nicht überschritten werden.
>> Wenn Du sie schnell hintereinander sendest, kann es also durchaus> passieren, dass sie zu einem Paket zusammengefasst werden - im Idealfall> so, dass die Path MTU ausgereizt wird und somit der geringste Overhead> entsteht.
Soweit ich weiß ist tcp/ip zuständig die Pakete zu fragmentieren und
danach wiederherzustellen. Also die Daten werden ankommen aber langsamer
halt. Verstehe ich das richtig?
>> Wenn Du die Verbindung zwischendurch trennst oder einen Moment wartest,> hebelst Du dieses Verhalten aus.
kann man ausrechnen wie viel man mindestens warten muss, damit das ganze
ohne Fragmentation funktioniert?
Stefan ⛄ F. schrieb:> Hmmm schrieb:>> Du verstehst einen grundlegenden Punkt von TCP falsch: Im Gegensatz zu>> UDP hast Du keinen Einfluss darauf, wie der TCP-Stack die gesendeten>> Daten in Pakete verpackt.>> Dazu kommt, dass jede Netzwerk-Komponente (z.B. Router) die Stückelung> des TCP Datenstroms ändern darf.
ja genau und darauf habe ich geachtet, dass mein MTU von dem Router,
ESP-Board auf 1500 Byte sind und dass meine Paketgröße nicht 900 Byte
überschreitet.
>> Es gibt immer wieder Produkte, die wegen Missachtung dieses Fakts> Probleme machen. Das war schon vor 30 Jahren so, und heute immer noch.
Hammad S. schrieb:> Soweit ich weiß ist tcp/ip zuständig die Pakete zu fragmentieren und> danach wiederherzustellen.
Nein, niemand garantiert dir, dass die Pakete bei TCP in der
ursprünglichen Stückelung beim Empfänger ankommen. Denn TCP ist in
Gegensatz zu UDP nicht Paket orientiert.
TCP stellt nur sicher, dass dein Datenstrom korrekt fließt. Dass heißt:
Die Bytes kommen in der richtigen (ursprünglichen) Reihenfolge beim
Empfänger an und werden durch Störsignale nicht verfälscht. Entweder
fließt der Strom, oder er wird vom Netzwerk Treiber unterbrochen.
Falsche Daten gibt es bei TCP nicht.
Aber auf due Stückelung der Daten in Form von Paketen ist keinerlei
Verlass. Wenn du da brauchst, musst du UDP verwenden. UDP garantiert
aber nicht, dass die Pakete in der richtigen Reihenfolge ankommen. Es
dürfen auch welche verloren gehen.
Lies dazu dies:
https://serverfault.com/questions/534063/can-tcp-and-udp-packets-be-split-into-pieces
Hammad S. schrieb:>> Da kommen erst Dein MQTT-Publish, dahinter folgt aber plötzlich noch ein>> zweiter Datensatz. Siehe beigefügter Screenshot, der markierte Bereich>> ist die eigentliche Publish-Message, der Rest gehört dort nicht hin.> ja das ist genau mein Problem
Das Problem ist die PubSubClient-Bibliothek. "It can only publish QoS 0
messages.", das heisst es wird nach einem PUBLISH nie auf einen PUBACK
gewartet. Tatsächlich wird nach einem PUBLISH noch nicht einmal ein
flush() ausgeführt.
Versuch das einmal selbst. Ruf nach client.publish() mal
espClient.flush() auf. Vielleicht zwingt das das TCP-Paket raus, und
verhindert das sich der nächste PUBLISH hinten ans selbe Paket noch dran
klebt.
LG, Sebastian
Hammad S. schrieb:> Ich habe darauf geachtet, dass meine> Pakete wegen die MTUs die 1500 Bytes nicht überschritten werden.
Das ist bei TCP unnötig, darum kümmert sich komplett der TCP/IP-Stack.
Du kannst daher beliebig Daten raussenden, und am anderen Ende kommen
sie in derselben Reihenfolge (aber ggf. in anderen Paketgrössen) wieder
raus.
Beachten musst Du dabei im wesentlichen zwei Dinge:
1. Der TX-Buffer ist nicht unendlich gross, es kann also passieren, dass
mal keine Daten (oder nur ein Teil davon) rausgesendet werden können.
Darum dürfte sich hier die verwendete Library kümmern.
2. Die empfangende Seite kann beim read()/recv() sowohl einen Bruchteil
eines abgesendeten Datenpakets als auch mehrere davon direkt
hintereinander bekommen und muss damit umgehen können.
Hammad S. schrieb:> Soweit ich weiß ist tcp/ip zuständig die Pakete zu fragmentieren und> danach wiederherzustellen. Also die Daten werden ankommen aber langsamer> halt. Verstehe ich das richtig?
Ja, im schlimmsten Fall steigt der Overhead.
Was hier passiert, ist übrigens auch keine Fragmentierung (die passiert
auf IP-Ebene, insbesondere durch Router), sondern Segmentierung.
Hammad S. schrieb:> kann man ausrechnen wie viel man mindestens warten muss, damit das ganze> ohne Fragmentation funktioniert?
Das ist implementationsabhängig. Ich würde mir darüber keine Gedanken
machen und die Daten so schnell schicken, wie es für die Anwendung
sinnvoll ist.
Hmmm schrieb:> [Einiges über TCP/IP]
Hammad benutzt eine MQTT-Client-Bibliothek (PubSubClient). Insofern hat
er auf all das wenig Einfluss.
LG, Sebastian
Sebastian W. schrieb:> Hmmm schrieb:>> [Einiges über TCP/IP]>> Hammad benutzt eine MQTT-Client-Bibliothek (PubSubClient). Insofern hat> er auf all das wenig Einfluss.
Das Problem sitzt aber doch auf der PC-Seite, oder? TCP wurde kompatibel
zur seriellen Schnittstelle entworfen. Beim Empfänger fällt ein Byte
nach dem anderen raus, keine Pakete.
Sebastian W. schrieb:> Hammad S. schrieb:>>> Da kommen erst Dein MQTT-Publish, dahinter folgt aber plötzlich noch ein>>> zweiter Datensatz. Siehe beigefügter Screenshot, der markierte Bereich>>> ist die eigentliche Publish-Message, der Rest gehört dort nicht hin.>> ja das ist genau mein Problem>> Versuch das einmal selbst. Ruf nach client.publish() mal> espClient.flush() auf. Vielleicht zwingt das das TCP-Paket raus, und> verhindert das sich der nächste PUBLISH hinten ans selbe Paket noch dran> klebt.
Hammad, hattest du Zeit meinen Vorschlag auszuprobieren?
LG, Sebastian
Sebastian W. schrieb:> Sebastian W. schrieb:>> Hammad S. schrieb:>>>> Da kommen erst Dein MQTT-Publish, dahinter folgt aber plötzlich noch ein>>>> zweiter Datensatz. Siehe beigefügter Screenshot, der markierte Bereich>>>> ist die eigentliche Publish-Message, der Rest gehört dort nicht hin.>>> ja das ist genau mein Problem>>>> Versuch das einmal selbst. Ruf nach client.publish() mal>> espClient.flush() auf. Vielleicht zwingt das das TCP-Paket raus, und>> verhindert das sich der nächste PUBLISH hinten ans selbe Paket noch dran>> klebt.>> Hammad, hattest du Zeit meinen Vorschlag auszuprobieren?>> LG, Sebastian
Hallo Sebastian,
sorry für die späte Antwort aber mein Laptop ist kaputt gegangen. Ich
habe es probiert aber hat leider nichts gebracht. Ich würde den
Vorschlag von @Hmmm nutzen und die Daten so weiter schicken auch wenn
die segmentiert werden.
Hmmm schrieb:>> Das ist implementationsabhängig. Ich würde mir darüber keine Gedanken> machen und die Daten so schnell schicken, wie es für die Anwendung> sinnvoll ist.
Vielen Dank für deine Antwort.
Wie kann ich am besten testen welchen Durchsatz meine WLAN-Verbindung
hat?
Im Datasheet steht 150Mb/s, was ich nicht realistisch finde
Hammad S. schrieb:> Ich habe es probiert aber hat leider nichts gebracht.
Ok. Ich hatte mir den EthernetClient Quellcode von flush() angeschaut,
da wird anscheinend der Hardware der Befehl zum Senden geheben; aber bei
ESP WiFi hab ich dann nicht mehr kontrolliert.
LG, Sebastian
Paul schrieb:> Was für ein Problem besteht denn?>> Das Verhalten mit 1490/235 Byte wurde oben ja schon erklärt und ist auch> völlig in Ordnung.
Ich will nur die WLAN-Datenrate ausrechnen
Hammad S. schrieb:> Ich will nur die WLAN-Datenrate ausrechnen
Das wird nichts, im Gegensatz zu Ethernet ist die nicht fest, sondern
hängt von vielen Faktoren ab.
Hmmm schrieb:> Das wird nichts, im Gegensatz zu Ethernet ist die nicht fest, sondern> hängt von vielen Faktoren ab.
Uns zwar so stark, dass ich zu Hause alles verkabele, was geht. Mein
Sohn hat sich sogar ein Ethernet Kabel zum Bett hin verlegt - für den
Laptop.
Man kann es auch übertreiben. Aber ich was damals nicht anders drauf,
deswegen sage ich nichts dazu.
Hmmm schrieb:> Hammad S. schrieb:>> Ich will nur die WLAN-Datenrate ausrechnen>> Das wird nichts, im Gegensatz zu Ethernet ist die nicht fest, sondern> hängt von vielen Faktoren ab.
das ist ja klar.
Ich habe die Datenrate mit Hilfe von Iperf getestet und hab 15.2 Mb/s
bekommen.