mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Websocketserver auf STM32, Fehler 1002


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Johannes S. (jojos)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
kennt sich hier jemand mit dem Websocket Protokoll aus?
Ich habe diesen Websocketserver für mbed-od portiert:
https://os.mbed.com/users/flatbird/code/WebSocketServer/
Wenn ich mich im lokalen Netz mit dem 'Simple Web Socket Client', einer 
Chrome Extension, verbinde, dann wird der Socket geöffnet und gleich 
wieder geschlossen. Im Wireshark wird ein Fehlercode 1002 beim Close 
gesendet.
Mache ich das gleiche mit dem Umweg über das Internet dann bleibt die 
Verbindung geöffnet, beim Senden kommt eine Warnung wegen segmentierter 
Pakete aber die Daten kommen im STM an.
Eine kleine Testapp in JavaScript kann sich Verbinden und Daten 
senden/empfangen.
Oder taugt die Chrome Extension nichts?
Fehler 1002: 
https://stackoverflow.com/questions/22587438/websocket-close-code-1002
Ein sehr allgemeiner Fehler im Protokoll wie es aussieht.

: Bearbeitet durch User
von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
ok, der Fehler liegt darin das dieser Parser nicht mit den zerstückelten 
PDUs umgehen kann. Es werden zuerst 536 Bytes gelesen, aber damit ist 
die Message nicht komplett. Es folgen weitere 14 Bytes die zum Fehler 
führen weil die der Rest des ersten Teils sind.

Woher weiss ich nun das der HTTP Get komplett ist? Ist es das doppelte 
/0x0d /0x0a im TCP Stream?

Edit:
Antwort:nein.

es sind die Bits am Anfang der Message. Hier wird das in rxMessage() 
wohl besser behandelt:
https://os.mbed.com/users/aktk/code/WS_SERVER//file/ccaae77f91b8/WS_SERVER.cpp/
Muss dann ein bisschen mischen. Manjana.

: Bearbeitet durch User
von hfhd (Gast)


Bewertung
0 lesenswert
nicht lesenswert
das erste paket ist noch http ( upgrade )

hier steht die länge im header
"Content Lenght: xxx"
der http parser muss dementsprechend so lange daten empfangen.


beim Websocket steht die länge im header

im header  jedes websocket paketes steht auch eich "FIN" Flag
das ist das letzte paket dieser nachricht.

ganz stumpf:
- solange daten in einen puffer schieben bis das FIN Flag kommt.
- wenn fin flag kommt , opcode prüfen und daten verwursten

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
danke, bin da gerade auch nochmal dran.
Ist das HTTTP Get nicht immer mit CR LF CR LF abgeschlossen und das als 
Endekennung zu interpretieren? Eine content length sehe ich da nicht.

aus RFC 7230:
A client sends an HTTP request to a server in the form of a request
message, beginning with a request-line that includes a method, URI,
and protocol version (Section 3.1.1), followed by header fields
containing request modifiers, client information, and representation
metadata (Section 3.2), an empty line to indicate the end of the
header section, and finally a message body containing the payload
body (if any, Section 3.3).

also erstmal lesen bis eine empty line kommt, müsste also richtig sein 
mit den CR LF.

: Bearbeitet durch User
von hfhd (Gast)


Bewertung
0 lesenswert
nicht lesenswert
nochmal gecshaut eben ...


das upgrade paket ist nur mit \r\n\r\n abgeschlossen

von Stefan F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Johannes S. schrieb:
> Ist das HTTTP Get nicht immer mit CR LF CR LF abgeschlossen und das als
> Endekennung zu interpretieren?

Ja.

1) Der Content-Length Header sagt, wie viele Bytes der Body groß ist. 
Bei HTTP-GET sollte der Body immer 0 Bytes groß sein. Daraus ergibt 
sich:

2) Ein HTTP Request mit leerem Body endet mit \r\n\r\n


Bei einer Response ist es etwas anders:

1) Der optionale(!) Content-Length Header sagt, wie viele Bytes der Body 
groß ist.

2) Ohne Content-Length Header muss der Server die Verbindung schließen, 
um das Ende zu signalisieren.

Bei HTTP 1.1 kann der Client dem Server mittels "Connection: close" 
Header vorschreiben, dass der Server die Methode 2 anwenden muss. Egal 
ob mit oder ohne Content-Length Header.

Bei HTTP 1.0 muss der Server die Verbindung immer schließen, egal ob mit 
oder ohne Content-Length Header.

: Bearbeitet durch User
von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
ok, so langsam wird es was. Habe zwar schon viele UDP und TCP 
Verbindungen programmiert, aber nie wirklich was mit HTTP gemacht, 
zumindest nicht auf dem low level.
Das doppelte CR LF habe ich in o.g. Komponente nachgestrickt. Es gibt da 
zwei Behandlungen, einmal wenn das noch HTTP ist und nach dem Upgrade 
wenn es ein Websocket ist. In der HTTP Behandlung lese ich jetzt solange 
bis ein doppeltes CRLF im Buffer ist.
Laut RFC7230 3.5.Message Parsing Robustness ist ein doppeltes CRLF auch 
nicht zwingend, das müsste auch noch aufwendiger gecheckt werden. Da 
gibt es doch bestimmt auch Testclients die verschiedene Fälle 
durchprobieren?

In dem Code von H.Hiratori war auch kein Senden vom Server an den Client 
dran, das habe ich auch eingebaut (wie in 
https://github.com/Links2004/arduinoWebSockets/tree/master/src).

Jetzt kann der Code immerhin einen Client bedienen, dann ist der Server 
im WebSocketConnection.run() gefangen, auch nicht schön. Also umbauen 
auf Threads, polling oder Events.

Und jetzt ist das eine eigene Server Komponente. Geschickter wäre sicher 
das in einen Webserver zu integrieren damit Websocket Requests auch über 
Port 80 (oder dem des Webservers) laufen können?

: Bearbeitet durch User

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.