[Python-de] Problem mit SocketServer

Eugen Ruppert nomail at nomail.de
Di Mai 7 15:37:04 CEST 2013


> Ich habe gestern mal direkt mit python sockets gearbeitet und dieses 
> Verhalten beobachtet. Obwohl ich die Puffergrößen exakt mit den 
> Nachrichtenlängen abgestimmt habe, gab es vereinzelt Überläufe / 
> Unterläufe, so dass in meinen Kommandovariablen auf einmal Nutzdaten 
> standen.
Ja, (ohne jetzt extra nachzuschlagen) würde ich sagen, dass es das
BSD-Socketverhalten ist ;)


> Jetzt habe ich vor eine Art String Matching einführen.
> D.h. ich gehe den Puffer Zeichen für Zeichen durch.

Wie gesagt, StreamRequestHandler oder "makefile(socket)" übernehmen für
einen schon die Pufferung und das "Blocklesen".

> Welches "Format" ist schnell zu matchen ? So etwas vielleicht: ?
> 
> .....###<CMD1>:8chars|<DATASIZE>:4chars|<DATA1>:DATASIZEchars>###.....
> 
Kommt darauf an, was Du machen möchtest. Ich würde auf jeden Fall
zuerst etwas auf dem "höheren Level" probieren.
JSON wäre ein Beispiel - zumindest kann man damit bequem dicts, listen,
und primitive Datentypen transportieren.

Server:
cmd_dict = json.loads(request.readline())
if cmd_dict['cmd'] == foo:
    some_data = cmd_dict['data1'] 
    ...

client:
my_cmd = {'cmd':'foo', 'data' : bar'}
stream.write(json.dumps(my_cmd) + '\n')


das halte ich für einfacher (und zuverlässiger, da schon ausgiebig
getestet), als selbstständig zu Parsen/Matchen ;)


Oder:
xmlrcp:
http://docs.python.org/2/library/simplexmlrpcserver.html#simplexmlrpcserver-example
Das Beispiel zeigt es eigentlich schon - man registriert einfach eine
Funktion, die remote ausgeführt werden kann. Daten & Co werden
automatisch über XML serialisiert.

Natürlich, wenn man nicht um jedes Byte kämpfen muss (allerdings halte
ich den Overhead bei JSON meist für recht vernachlässigbar).
Bsp:
--------------------------
>>> json.dumps([1,2,3])
'[1, 2, 3]'
>>> json.dumps({'cmd':'foo', 'simple_data':42,'data' : [1,2,3,4],
... 'komplex_data' :{'bar':1,'xyz':[100,200],'somestr': "hello world"}})

'{"cmd": "foo", "data": [1, 2, 3, 4], "simple_data": 42,
"komplex_data" : {"xyz": [100, 200], "bar": 1, "somestr": "hello
world"}}'
--------------------------
das ganze "lesbar":
>>> print json.dumps(..., indent=2)
{
  "cmd": "foo",
  "data": [
    1,
    2,
    3,
    4
  ],
  "simple_data": 42,
  "komplex_data": {
    "xyz": [
      100,
      200
    ],
    "bar": 1,
    "somestr": "hello world"
  }
}
Zugriff:
>>> json.loads(x)['data']
[1, 2, 3, 4]
>>> mycmd=json.loads(x)
>>> mycmd['cmd']
u'foo'
>>> mycmd['data']
[1, 2, 3, 4]
>>> mycmd['komplex_data']['xyz']
[100, 200]
-------------------------

Bei dem, was Du als Beispiel aufgeführt hast, kommt mir an erster Stelle
ASN (Abstract Syntax Notation) in den Sinn, welche aber imho etwas zu
"heavy" für ein kleines Projekt wäre.

Gruß
Eugen




Mehr Informationen über die Mailingliste python-de