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


von Johannes S. (Gast)



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.

von Johannes S. (Gast)


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.

von hfhd (Gast)


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. (Gast)


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:
1
A client sends an HTTP request to a server in the form of a request
2
message, beginning with a request-line that includes a method, URI,
3
and protocol version (Section 3.1.1), followed by header fields
4
containing request modifiers, client information, and representation
5
metadata (Section 3.2), an empty line to indicate the end of the
6
header section, and finally a message body containing the payload
7
body (if any, Section 3.3).

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

von hfhd (Gast)


Lesenswert?

nochmal gecshaut eben ...


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

von Stefan F. (Gast)


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.

von Johannes S. (Gast)


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?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.