Socket- falsches Format bei ankommenden Strings

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
MrWagner
User
Beiträge: 3
Registriert: Mittwoch 14. Mai 2014, 14:21

Hi,

ich hab mich Heute notgedrungen mal mit Python beschäftigt, da ich Java wegen zu hohem RAM-Verbrauch auf meinen Einplatinencomputer nocht nutzen möchte.


Prinzipiell möchte ich folgendes realisieren: Android Client > Python Server. Das funktioniert im Prinzip, nur habe ich momentan ein Problem mit den ankommenden Daten: http://www.ld-host.de/uploads/images/64 ... d09ef5.jpg

Bestimte Zeichenketten werden halt falsch dargestellt. In diesen Fall ist es die Zeichenkette "25" die vom Java-Client auf dem Smartphone an den Server geschickt wurde. Ich hab schon diverse Vorschläge aus dem Netz probiert, aber so 100% weiß ich nicht wo genau der Fehler liegt. In Sachen Python bin ich noch nicht so fit, den "Server" hab ich schnell mal mit Beispielen aus dem Netz zusammengestellt. Im Grunde soll das Ding nur "lauern" und erstmal nur Strings empfangen.

mfg
BlackJack

@MrWagner: Du kannst Dir mal die `repr()`-Form von dem anschauen was da ankommt, dann sieht man deutlicher was exakt an Bytes empfangen wurde.

Grundsätzlich sieht es aber so aus als wenn der Sender da *nicht* die beiden Bytes sendet, die die ASCII-Zeichenfolge '25' ergeben. Kann es sein dass da noch irgendwas davor gesendet wird?

Das Empfangen ist nicht robust, weil TCP ein Datenstrom ist und ein `recv()` einen beliebigen Teilausschnitt aus dem Anfang der Daten liefern kann. Ein fehlerfreier Server muss an dieser Stelle also damit klarkommen können das er mehr als einen `recv()`-Aufruf benötigen kann um die Daten zu lesen. Im schlimmsten Fall kann jeder Aufruf nur 1 Byte lesen.

Edit: Bezüglich Namensschreibweise und Einrücktiefe könntest Du mal einen Blick in den Style Guide for Python Code werfen.

Und Zeichenketten und Werte werden in Python üblicherweise nicht durch ``+`` und `str()` zusammengesetzt, sondern mit der `format()`-Methode auf Zeichenketten. (Dachte sowas hätte sich bei Java mittlerweile auch durchgesetzt.)
MrWagner
User
Beiträge: 3
Registriert: Mittwoch 14. Mai 2014, 14:21

Jo, es wird noch was davon gesendet: repr(data) ergibt: '\x00\x0225' für "25" und für "Hallo" '\x00\x05Hallo'.

Ich hatte ganz am Anfang mal die Idee das einfach zu replacen, aber so ganz koscher war mir die Idee dann nicht. Da gibt es doch sicher einen eleganteren Weg?

Und danke für den Style-Guide und den Hinweis mit dem Datenstrom.
BlackJack

@MrWagner: Na das sieht doch so aus als wenn die Daten mit einer 16-Bit-Zahl anfangen in der die Länge gespeichert ist. Ist der Code der das sendet nicht von Dir? Hast Du eine Protokollbeschreibung?
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@MrWagner: ohne die Länge der Nachricht zu wissen, kannst Du ja nicht wissen, wann sie zu Ende ist. Die zwei ersten Bytes einfach wegzuschmeißen, wäre also ziemlich blöd.
MrWagner
User
Beiträge: 3
Registriert: Mittwoch 14. Mai 2014, 14:21

Auf der Gegenseite hängt halt erstmal was total simples.

DataOutputStream dos = new DataOutputStream(clientSocket.getOutputStream());
dos.writeUTF("Hello");

Da muss ich an der Stelle noch mal schauen.
BlackJack

@MrWagner: Ja, das ist da dokumentiert das erst 16-Bit gesendet werden, die die Länge in Bytes angeben. Und was da gesendet wird ist ”modifiziertes” UTF-8. Wenn Du das mit etwas anderem als Java verarbeiten möchtest, müsstest Du schauen was da genau anders gemacht wird.
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ist ja nett: Surrogate-Paare werden automatisch umgewandelt. Bliebe nur noch das 0-Byte:

Code: Alles auswählen

text = data.replace('\xC0\x80', '\0').decode('utf8')
Das Encodieren wird da schon schwieriger.
Antworten