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.
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.
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
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.
nochmal gecshaut eben ... das upgrade paket ist nur mit \r\n\r\n abgeschlossen
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.