[Python-de] Problem mit SocketServer
Eugen Ruppert
nomail at nomail.de
Mo Mai 6 18:09:03 CEST 2013
Hallo Alexander,
> Socket-Objekte blockieren per default. Zitat:
[...snip...]
> SocketServer.recv() blockiert jedoch nicht. Folglich läuft die while
> Schleife durch und meine CPU-Last steigt auf 25%.
>
> Dieses non-blocking Verhalten ist auch nicht dokumentiert.
> Anscheinend ging der Autor davon aus dass man nur Requests im Stile
> von HTTP absetzt :/
Was aus der Dokumentation nicht direkt ersichtlich ist: ein recv Aufruf
liefert einen leeren String, wenn die Gegenseite nicht mehr da ist:
http://docs.python.org/2/howto/sockets.html
Da recv(X) dann sofort zurückkehrt, ist das Verhalten durchaus mit
non-blocking vergleichbar. Also solltest Du zumindest ein:
if not self.data: break
einbauen.
Grundsätzlich würde ich aber davon abraten, recv(BUFF_SIZE) aufzurufen,
da man dann z.B zusätzlich prüfen muss, wie viele Daten ein recv()
überhaupt liefert. Es klappt zwar sehr oft (besonders im lokalen
Netzwerk ;) ), dass ein recv den ganzen Datenblock einließt, verlassen
darf man sich darauf nicht - es kann genauso 1 Byte sein.
Hier hilft StreamRequestHandler weiter oder ein makefile(socket).
import SocketServer
class MyTCPHandler(SocketServer.StreamRequestHandler):
def handle(self):
while True:
self.data = self.rfile.readline().strip()
if not self.data:
break
print self.data
self.wfile.write(self.data.upper())
server = SocketServer.TCPServer(("localhost",2000), MyTCPHandler)
server.serve_forever()
Gut, dieses Beispiel schließt die Verbindung auch bei leeren
Zeilen (wobei dieses Verhalten gar nicht so unerwünscht sein könnte),
man könnte allerdings auch "read(MAX)" verwenden (dieses liest dann
entweder X Zechen oder bis zum EOF).
Eugen
Mehr Informationen über die Mailingliste python-de