asyncore tcp proxy unverstaendliche 80% cpu auslastung

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
xilef
User
Beiträge: 3
Registriert: Donnerstag 21. Dezember 2006, 20:22

Donnerstag 21. Dezember 2006, 20:37

Heyho Python Freunde,

ich verstehe nicht ganz warum unten stehender TCP Proxy 90% CPU Last erzeugt. Ich denke ich habe da etwas nicht ganz richtig implementiert, aber die Dokumentation von asyncore lieferte mir auch keine Hinweise. Ich nehme an dass recv(1) zuviel CPU Last erzeugt, aber ich will eigentlich einen Protokoll unabhaengigen TCP Proxy der Byte-weise funktioniert. Also kommt die Funktionalitaet mit set_terminator nicht in Frage.
Es ist ausserdem noch so dass der Proxy nicht nur Last erzeugt, die Verbindung ist ausserdem merklich langsamer.

Faellt euch da was auf wie ich es 'richtig' (tm) haette machen koennen so dass keine 90% CPU Last erzeugt werden?

Zur Info: System: Mac OS X macports python 2.4 (Python 2.4.3 (#1, Nov 16 2006, 20:47:32) GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin)

Code: Alles auswählen

import asyncore, socket

class proxy_server(asyncore.dispatcher):
	def __init__(self, host, port):
		asyncore.dispatcher.__init__ (self)
		self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
		self.set_reuse_addr()
		self.there = (host, port)
		self.here = ('', 64000)
		self.bind(self.here)
		self.listen(100)
		print "SERVER: init done"

	def handle_accept(self):
		print "SERVER: got accept"
		proxy_receiver(self, self.accept())

class proxy_receiver(asyncore.dispatcher):
	def __init__(self, server, (conn, addr)):
		asyncore.dispatcher.__init__(self, conn)
		self.server = server
		self.sender = proxy_sender(self, server.there) # remote
		print 'RECVER: <init done>'

	def handle_connect(self):
		print 'RECVER: <open connection>'

	def handle_close(self):
		print 'RECVER: <close connection>'
		self.sender.close()
		self.close()
	
	def handle_write(self):
		pass
	
	def handle_read(self):
		pass
		# print "RECVER: <READ>"
		self.sender.send(self.recv(1))

class proxy_sender(asyncore.dispatcher):
	def __init__(self, receiver, address):
		asyncore.dispatcher.__init__(self)
		self.receiver = receiver
		self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
		self.connect(address)
		print 'SENDER: <init done>'

	def handle_connect(self):
		print 'SENDER: <open connection>'

	def handle_close(self):
		print 'SENDER: <close connection>'
		self.close()
		self.receiver.close()
	
	def handle_write(self):
		pass

	def handle_read(self):
		pass
		# print "SENDER: <READ>"
		self.receiver.send(self.recv(1))

ps = proxy_server("localhost", 80)
asyncore.loop()
xilef
User
Beiträge: 3
Registriert: Donnerstag 21. Dezember 2006, 20:22

Donnerstag 21. Dezember 2006, 20:46

hrmpf...

i will use google before asking stupid questions...

http://mail.python.org/pipermail/python ... 59791.html
xilef
User
Beiträge: 3
Registriert: Donnerstag 21. Dezember 2006, 20:22

Donnerstag 21. Dezember 2006, 20:58

die folgende Version funktioniert. Hat jedoch seltsamerweise immernoch circa 40% CPU peaks...

ausserdem werden die Sockets nicht richtig geschlossen. (Edit: fixed)

Ich hoffe irgendwen interessierts :)

Code: Alles auswählen

import asyncore
import socket

class proxy_server(asyncore.dispatcher):
	def __init__(self, host, port):
		asyncore.dispatcher.__init__ (self)
		self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
		self.set_reuse_addr()
		self.there = (host, port)
		self.here = ('', 64000)
		self.bind(self.here)
		self.listen(100)
		print "SERVER: init done"

	def handle_accept(self):
		print "SERVER: got accept"
		proxy_receiver(self, self.accept())

class proxy_receiver(asyncore.dispatcher):
	def __init__(self, server, (conn, addr)):
		asyncore.dispatcher.__init__(self, conn)
		self.server = server
		self.sender = proxy_sender(self, server.there) # remote
		print 'RECVER: <init done>'

	def handle_connect(self):
		print 'RECVER: <open connection>'

	def handle_close(self):
		print 'RECVER: <close connection>'
		self.sender.close()
		self.close()

	def writable(self):
		return False
			
	def handle_read(self):
		# print "RECVER: <READ>"
		try:
			self.sender.send(self.recv(1))
		except:
			# print "RECVER: <READ FAILED>"
			pass

class proxy_sender(asyncore.dispatcher):
	def __init__(self, receiver, address):
		asyncore.dispatcher.__init__(self)
		self.receiver = receiver
		self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
		self.connect(address)
		print 'SENDER: <init done>'

	def handle_connect(self):
		print 'SENDER: <open connection>'

	def handle_close(self):
		print 'SENDER: <close connection>'
		self.receiver.handle_close()
	
	def writable(self):
		return False

	def handle_read(self):
		print "SENDER: <READ>"
		try:
			self.receiver.send(self.recv(1))
		except:
			# print "SENDER: <READ FAILED>"
			pass


ps = proxy_server("localhost", 80)
asyncore.loop()
Antworten