Schei� encoding

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
BlackJack

@Py-Prog: Würde ich auch so sehen.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

@Hyperion geht Bitstring auch?
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@Py-Prog: Ich kenne das nicht; aber probiere es doch ruhig mal aus. Auf den ersten Blick sah die Doku ganz brauchbar aus.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Nächstes Problem:
Ich hab's mit BitString zum laufen gebracht, aber jetzt hab ich das gleiche Problem wie vorher, wenn der Server oder der Client zwei Pakete so kurz hintereinander schickt, das ich beide mit read(10000) auslese, dann funktioniert es nicht mehr, ich müsste also für jedes Paket ein elif einbauen, was aber aus Geschwindigkeits-gründen auf gar keinen Fall infrage kommt, nur wenn es keine andere Lösung gibt. Gibt es einen Möglichkeit die geschickten Pakete einzeln hintereinander auszulesen?
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Py-Prog hat geschrieben:... wenn der Server oder der Client zwei Pakete so kurz hintereinander schickt, das ich beide mit read(10000) auslese, dann funktioniert es nicht mehr, ...
Code? Fehlermeldung? Wir haben doch keinen Plan, was Du da genau machst...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Py-Prog: Aus dem Inhalt der einzelnen Pakete wird doch klar wie lang sie jeweils sind. Da das Protokoll kein allgemeines Längenfeld besitzt, muss der Code leider *alle* Pakete verstehen können, damit man nicht aus dem Tritt kommt.

Es wird TCP verwendet, also musst Du nicht nur damit rechnen mehr als ein Paket mit einem `read()`-Aufruf zu bekommen, sondern auch damit, dass Du *unvollständige* Pakete bekommen kannst, wo Du erst mit dem einem, oder womöglich sogar mehreren `read()`-Aufrufen den Rest der Daten bekommst. Damit muss Dein Code klar kommen können.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

BlackJack hat geschrieben:Es wird TCP verwendet, also musst Du nicht nur damit rechnen mehr als ein Paket mit einem `read()`-Aufruf zu bekommen, sondern auch damit, dass Du *unvollständige* Pakete bekommen kannst, wo Du erst mit dem einem, oder womöglich sogar mehreren `read()`-Aufrufen den Rest der Daten bekommst. Damit muss Dein Code klar kommen können.
Daher ist ja ØMQ so interessant: Low-level aber mit Komfortfunktionen und manchmal schneller als TCP allein.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Bau dir einen Buffer mit dem io-Modul, in welchen du deinen ankommenden Daten schreibst, anschließend parst du die Packete aus dem Buffer.
the more they change the more they stay the same
BlackJack

@Dav1d: Welchen Vorteil bringt das? Den Puffer kann man sich doch auch ganz einfach aus Zeichenketten selbst bauen.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Um das Minecraft-Protokoll richtig parsen zu können brauchst du immer eine bestimmte Anzahl an Bytes, da ist ein einfaches buffer.read(bytes) einfacher und mMn auch schöner als buffer_str[:bytes], buffer_str = buffer_str[bytes:].
the more they change the more they stay the same
BlackJack

@Dav1d: Ach so, dann willst Du keine Pakete lesen, sondern die Einzelteile von den Paketen. Das geht natürlich auch.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Dann hoffe ich dass das mit den vielen elif abfragen immer noch schnell genug ist ...
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
deets

Ohne Code ist dazu natuerlich nicht viel zu sagen - aber ich behaupte mal, die vielen elifs sind mindestens mal schlecht programmiert. Denn wenn man Netzwerkprogrammierung betreibt, muss man halt das Protokoll implementieren. Was du nicht zu tun scheinst.

Und das profiling mit Python geht sollte dir eigentlich bekannt sein, oder?
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

BlackJack hat geschrieben:@Dav1d: Ach so, dann willst Du keine Pakete lesen, sondern die Einzelteile von den Paketen. Das geht natürlich auch.
Das musst du sogar, weil es im Minecraft-Protokoll keinen Paket-Delimiter gibt, liest du einmal falsch, musst du neu connecten. Die einzige Möglichkeit die Pakete zu erzeugen ist es byte für byte zu lesen.
the more they change the more they stay the same
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Ach, ich habe nochmal meine IRC-Logs durchgeschaut ... es gibt schon einen funktionierenden Minecraftprotokoll-Parser in Python https://github.com/barneygale/barneymc (Es gibt mindestens noch einen weiteren, allerdings habe ich den Link auf die schnelle nicht gefunden)
the more they change the more they stay the same
BlackJack

@Dav1d: Ich weiss wie die Pakete aussehen, ich hätte trotzdem nicht für jedes Stück einen eigenen `read()`-Aufruf gemacht. Weil ich ja `io` nicht benutzt hätte.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

@BlackJack, wie hättest du das gemacht? Mit Strings als Buffer?
the more they change the more they stay the same
BlackJack

@Dav1d: Ja, ich hätte die Funktionen zum Parsen der einzelnen Pakete so geschrieben, dass sie eine Ausnahme werfen wenn es nicht vollständig war und ansonsten zurück geben wie lang das Paket war. Wenn Pakete nicht vollständig sind, nicht besonders effizient, aber ich vermute so oft kommt das nicht vor.

Das ganze in einen entsprechenden Reader zu verpacken und dann eine `read()`-Methode zu haben, die auch (fast) garantiert die angeforderte Anzahl von Bytes liefert, ist natürlich schöner.
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

Vielleicht solle ich mal sagen das die Pakete (in diesen Fall) eigentlich immer Komplett sind, das Problem tritt nur bei einem Freund von mir auf und der hat ein ziemlich lames Internet und dann kleben die Pakete nur hintereinander, aber komplett.
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
BlackJack

@Py-Prog: Das ist vollkommen egal was bei Dir oder Deinem Freund passiert, wichtig ist was grundsätzlich passieren kann. Wenn der Code nicht mit unvollständigen Paketen bei einem `read()` von einem `socket`-Objekt klar kommt, ist er schlicht kaputt und keine korrekte, brauchbare Implementierung des Protokolls. Denn so etwas kann, darf, und wird im realen Einsatz einfach irgend wann einmal bei irgend wem passieren.
Antworten