[Python] Websocket server ontvangt data niet correct

Pagina: 1
Acties:
  • 789 views

Onderwerpen


Acties:
  • 0 Henk 'm!

  • WernerL
  • Registratie: December 2006
  • Laatst online: 17:45
Vandaag en gisteren ben ik in Python aan het prutsen geweest om een simpele server te schrijven welke communicatie mogelijk moet maken tussen webpagina's. Nouja, om precies te zijn moet hij iPads laten communiceren welke mbv Phonegab geschreven worden.

Nu loop ik tegen 2 problemen aan, de Safari browser op de iPad houdt de connectie niet in stand, hij maakt verbinding, ik stuur een (volgens mij) correcte handshake terug en Safari disconnect vervolgens. :(

De debugconsole van safari maakt verder geen error over dat de handshake verkeerd is dus het lijkt mij dat het correct is wat ik doe. Hieronder de functie die de handshake genereerd:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
        def create_handshake_resp( self, handshake):
                final_line = ""
                lines = handshake.splitlines()
                for line in lines:
                        parts = line.partition(": ")
                        if parts[0] == "Sec-WebSocket-Key1":
                                key1 = parts[2]
                        elif parts[0] == "Sec-WebSocket-Key2":
                                key2 = parts[2]
                        elif parts[0] == "Host":
                                host = parts[2]
                        elif parts[0] == "Origin":
                                origin = parts[2]
                                final_line = line

                spaces1 = key1.count(" ")
                spaces2 = key2.count(" ")
                num1 = int("".join([c for c in key1 if c.isdigit()])) / spaces1
                num2 = int("".join([c for c in key2 if c.isdigit()])) / spaces2

                token = hashlib.md5(struct.pack('>II8s', num1, num2, final_line)).digest()

                return (
                "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
                "Upgrade: WebSocket\r\n"
                "Connection: Upgrade\r\n"
                "Sec-WebSocket-Origin: %s\r\n"
                "Sec-WebSocket-Location: ws://%s/\r\n"
                "\r\n"
                "%s") % (
                origin, host, token)


Chrome heeft WEL de laatste implementatie van websockets dus die gebruikt een andere functie voor de handshake, mischien werkt hij daarom wel in Chrome, maar ik weet dus niet of het aan mijn handshake ligt. Maar in de Chrome implementatie is het hele algoritme wat ik heb nog maar slechts 2 regels...

Het 2e probleem wat ik heb is dat de data niet correct aankomt. De headers tijdens de handshake zijn wel in echte tekst, maar zodra de verbinding tot stand is gebracht (nu in Chrome want die disconnect niet) dan ziet de data er zo uit:

� �|DE]

Tjah, wat moet ik hier dan mee. :') Allemaal rare tekens, alsof hij binaire data ontvangt ofzo?
En helaas lukt het me niet om er achter te komen waar dit probleem dan ligt. Ik heb al geprobeerd om de data te decoden in utf-8 formaat maar helaas mocht dat niet baten.
Dit is de functie die inkomende berichten ophaalt:
code:
1
2
3
4
        def recv_data(self, client, count):
                data = client.recv(count)
                return data
                #return data.decode('utf-8', 'ignore')


Mijn gevoel zegt dat dit gewoon moet werken... :+ Zijn er toevallig meer mensen die wel eens een websocket server hebben gebouwd? Want ik begrijp helemaal niets van dit gedrag van de socketserver. Ik heb voorbeelden bekeken op het internet maar ik lijk het toch niet anders te doen dan andere mensen.

Als ik nou zou weten wat er dan precies fout gaat kan ik het oplossen, ik hoop dat iemand mij daar mee kan helpen. :-)

Roses are red, violets are blue, unexpected '{' on line 32.


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Unicode Character 'REPLACEMENT CHARACTER'. Dat zie je ook aan de manier waarop 't forum je bericht heeft opgeslagen; als je nu op edit/view zou klikken zie je � staan.

The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

Verder heb ik geen idee wat er verder precies gaande is of aan de hand zou kunnen zijn, maar met een wireshark sessie oid kom je meestal een heel eind.

[ Voor 79% gewijzigd door RobIII op 13-04-2012 01:12 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • oxfordpelican
  • Registratie: Februari 2003
  • Laatst online: 18:07
Welke WebSocket versie gebruikt Safari?

Acties:
  • 0 Henk 'm!

  • WernerL
  • Registratie: December 2006
  • Laatst online: 17:45
Volgens mij gebruikt Safari nog de versie van een jaar geleden. Chrome stuurt iig een versienummer mee, en dat is versie 13. Zou als het goed is de laatste versie moeten zijn. Met Safari krijg ik echter 2 keys bij de server, met Chrome maar 1. Ik gok dus dat de Safari implementatie de oude is en dat ze besloten hebben dat 1 key wel genoeg is. :P

Wireshark heb ik ook al gedraaid maar ik krijg daar nog niet echt nuttige info uit. Ik zie net trouwens dat de token die ik voor Safari genereer ook niet goed encoded wordt. :+ Eerst dat eens proberen te fixen.

Roses are red, violets are blue, unexpected '{' on line 32.


Acties:
  • 0 Henk 'm!

  • The Will
  • Registratie: Mei 2001
  • Laatst online: 11-09 23:31
Zo te zien pak je de laatste line er niet lekker uit waardoor je response niet klopt. Als ik je code zo zie wordt de regel met "Origin: " gepakt als final_line, terwijl dat, zoals de naam al zegt, de laatste line zou moeten zijn. Daar staat immers de derde key in

Je probleem met data ontvangen ligt vermoedelijk in het feit dat je het pakket niet correct behandeld. WebSocket data wordt verstuurd in frames, welke verschillen per specificatie. Hybi-00 gebruikt enkel Start/End of frame bytes, RFC6455 redelijk uitgebreide frames. Daarbij komt dat in RFC6455 Client -> Server communicatie ook nog eens gemasked wordt. Ik zou even de RFC bestuderen: http://tools.ietf.org/html/rfc6455#section-5.2

There is no magic.


Acties:
  • 0 Henk 'm!

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09 23:18

djc

Ik heb ook een WebSockets-servertje geschreven in Python, en het lezen van de RFC was inderdaad best prima te doen, dus dat is aan te raden. (Ik heb het alleen getest met desktop Firefox/Chrome, maar als je mijn code wil hebben moet je maar even DM'en.)

Rustacean


Acties:
  • 0 Henk 'm!

  • WernerL
  • Registratie: December 2006
  • Laatst online: 17:45
Ow idd lekker handig, ik ging er vanuit dat ik slechts 2 keys hoefde te gebruiken samen met 8 ŕandom bytes.. :') Dan moet die handshake wel te fixen zijn. Was me nog niet opgevallen dat safari nog meer data meestuurt onderaan de request.

Het lezen van de data ben ik ook al mee bezig geweest, het werkt nog niet helemaal maar volgens mij gaat dat wel lukken, mocht ik er niet uitkomen dan post ik het hier nog wel of ik DM djc voor voorbeeld code. :P

Roses are red, violets are blue, unexpected '{' on line 32.


Acties:
  • 0 Henk 'm!

  • WernerL
  • Registratie: December 2006
  • Laatst online: 17:45
Even een klein kickje, maar het is me gelukt. Met zowel de laatste implementatie van websockets als ook de oude versie die de safari browser op de iPad nog gebruikt. Het unmasken van de data bleek niet zo moeilijk te zijn, je moet alleen even weten hoe de data verpakt zit. Hierbij wil ik wel even mijn python functie met de wereld delen :P

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def encodeData(self, fin, msg):
                print "Sending message to device #" + str(self.uid) + ": " + msg
                if fin:
                        finbit = 0x80
                else:
                        finbit = 0
                #het is tekst, als het om binaire data gaat moet deze op 0x2 staan geloof ik.
                opcode = 0x1

                frame = struct.pack("B", finbit | opcode)
                l = len(msg)
                if l < 126:
                        frame += struct.pack("B", l)
                elif l <= 0xFFFF:
                        frame += struct.pack("!BH", 126, l)
                else:
                        frame += struct.pack("!BQ", 127, l)
                frame += msg

                self.channel.send(frame)
        #data die binnenkomt terugzetten in een string
        def decodeData(self, msg):
                msg = bytearray(msg)
                length_code = len(msg[1:])
                masks = 0
                data = 0

                if length_code == 126:
                        masks = msg[4:8]
                        data = msg[8:]
                elif length_code == 127:
                        masks = msg[10:14]
                        data = msg[14:]
                else:
                        masks = msg[2:6]
                        data = msg[6:]

                for x in range(len(data)):
                        data[x] = data[x]^masks[x%4]
                return data


De volgende uitdaging wordt binaire data gaan versturen, ik moet namelijk foto's over een socket verbinding kunnen pompen en ik wil op een .png file uitkomen, maar hier heb ik tot zover nog geen hulp bij nodig. :P Iedereen die in dit topic gepost heeft iig bedankt.

[ Voor 6% gewijzigd door WernerL op 15-04-2012 21:25 ]

Roses are red, violets are blue, unexpected '{' on line 32.


Acties:
  • 0 Henk 'm!

Verwijderd

Ik heb een WebSocket Server gebouwd in Perl.
Daar heb ik m'n IRC bot ingebouwd als client, en dan handelt ie alles Round Robin af.
Voor de demo: *snip* spam (100% puur HTML5/CSS3)

Voor vragen: mailto:*snip*@gmail,com

[ Voor 18% gewijzigd door RobIII op 13-11-2015 17:57 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op vrijdag 13 november 2015 @ 17:01:
Ik heb een WebSocket Server gebouwd in Perl.
Daar heb ik m'n IRC bot ingebouwd als client, en dan handelt ie alles Round Robin af.
Voor de demo: *snip* spam (100% puur HTML5/CSS3)

Voor vragen: mailto:*snip*@gmail,com
Hier hebben we 't [Alg] Welke tools heb jij gemaakt? - deel IV topic voor maar als je daar alleen maar komt een een link en je e-mail adres te dumpen dan kun je je die moeite vast sparen. Als je wat relevante code hebt om te tonen of iets hebt dat discussiewaardig is dan zien we dat graag, zo niet dan zie ik geen nut in je post. Tevens heeft het ook geen nut een topic van meer dan 3(!) jaar oud te kicken, zéker niet als het, at best, zijdelings gerelateerd is en eigenlijk helemaal niets toevoegt / oplost van het originele probleem dat TS had...

[ Voor 7% gewijzigd door RobIII op 13-11-2015 17:59 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Pagina: 1

Dit topic is gesloten.