Heim >Backend-Entwicklung >Python-Tutorial >HTTP-Proxyserver
Vor Kurzem habe ich vor, mich eingehend mit der Python-Socket-Programmierung zu befassen, daher finde ich, dass es nicht einfach ist, gut zu schreiben. Es ist leicht zu erkennen, aber schwierig zu tun
import socket import thread import urlparse import select BUFLEN=8192 class Proxy(object): def __init__(self,conn,addr): self.source=conn self.request="" self.headers={} self.destnation=socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.run() def get_headers(self): header='' while True: header+=self.source.recv(BUFLEN) index=header.find('\n') if index >0: break #firstLine,self.request=header.split('\r\n',1) firstLine=header[:index] self.request=header[index+1:] self.headers['method'],self.headers['path'],self.headers['protocol']=firstLine.split() def conn_destnation(self): url=urlparse.urlparse(self.headers['path']) hostname=url[1] port="80" if hostname.find(':') >0: addr,port=hostname.split(':') else: addr=hostname port=int(port) ip=socket.gethostbyname(addr) print ip,port self.destnation.connect((ip,port)) data="%s %s %s\r\n" %(self.headers['method'],self.headers['path'],self.headers['protocol']) self.destnation.send(data+self.request) print data+self.request def renderto(self): readsocket=[self.destnation] while True: data='' (rlist,wlist,elist)=select.select(readsocket,[],[],3) if rlist: data=rlist[0].recv(BUFLEN) if len(data)>0: self.source.send(data) else: break def run(self): self.get_headers() self.conn_destnation() self.renderto() class Server(object): def __init__(self,host,port,handler=Proxy): self.host=host self.port=port self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server.bind((host,port)) self.server.listen(5) self.handler=handler def start(self): while True: try: conn,addr=self.server.accept() thread.start_new_thread(self.handler,(conn,addr)) except: pass if __name__=='__main__': s=Server('127.0.0.1',8080) s.start() import socket import thread import urlparse import select BUFLEN=8192 class Proxy(object): def __init__(self,conn,addr): self.source=conn self.request="" self.headers={} self.destnation=socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.run() def get_headers(self): header='' while True: header+=self.source.recv(BUFLEN) index=header.find('\n') if index >0: break #firstLine,self.request=header.split('\r\n',1) firstLine=header[:index] self.request=header[index+1:] self.headers['method'],self.headers['path'],self.headers['protocol']=firstLine.split() def conn_destnation(self): url=urlparse.urlparse(self.headers['path']) hostname=url[1] port="80" if hostname.find(':') >0: addr,port=hostname.split(':') else: addr=hostname port=int(port) ip=socket.gethostbyname(addr) print ip,port self.destnation.connect((ip,port)) data="%s %s %s\r\n" %(self.headers['method'],self.headers['path'],self.headers['protocol']) self.destnation.send(data+self.request) print data+self.request def renderto(self): readsocket=[self.destnation] while True: data='' (rlist,wlist,elist)=select.select(readsocket,[],[],3) if rlist: data=rlist[0].recv(BUFLEN) if len(data)>0: self.source.send(data) else: break def run(self): self.get_headers() self.conn_destnation() self.renderto() class Server(object): def __init__(self,host,port,handler=Proxy): self.host=host self.port=port self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server.bind((host,port)) self.server.listen(5) self.handler=handler def start(self): while True: try: conn,addr=self.server.accept() thread.start_new_thread(self.handler,(conn,addr)) except: pass if __name__=='__main__': s=Server('127.0.0.1',8080) s.start()
Tatsächlich ist der HTTP-Proxyserver selbst nicht schwierig, aber das Schreiben ist ziemlich mühsam. Ich werde hier nicht im Detail auf den Quellcode eingehen, er ist sehr einfach. Sprechen Sie hauptsächlich über die Probleme, auf die ich gestoßen bin.
1: Ursprünglich wusste ich nur, dass der erste Parameter von thread.start_new_thread ein Funktionsobjekt ist, aber als ich den obigen Blog-Beitrag sah, war ich fassungslos, also habe ich ihn schnell getestet 🎜>
import thread class Hello: def __init__(self,content): print content def cs(): thread.start_new_thread(Hello, ("Hello World",)) if __name__=='__main__': cs() import thread class Hello: def __init__(self,content): print content def cs(): thread.start_new_thread(Hello, ("Hello World",)) if __name__=='__main__': cs()Unbehandelte Ausnahme in Thread, gestartet durch
Fehler in sys.exclushook:
Ursprüngliche Ausnahme war:
Ursprüngliche Ausnahme war:
Lassen Sie mich auf den ersten Blick sagen, wie kann der erste Parameter ein Objekt sein? Ich habe gelacht und den Autor ein wenig verachtet. Also ging ich am nächsten Tag immer noch nicht auf, also lud ich den Code herunter und probierte ihn vor Ort aus. Mir war sofort klar, dass ich es war, also ging ich sofort zu Baidu.
Es stellt sich heraus, dass im Thread-Modul diese Ausnahme ausgelöst wird, wenn der Hauptthread vor dem untergeordneten Thread endet. Der einfachste Weg besteht darin, den untergeordneten Thread zuerst enden zu lassen Ich scheine lange genug zu schlafen, aber wie kann ich das Problem lösen?
Eine bessere Lösung besteht darin, dass der Hauptthread jedem Unterthread eine Sperre hinzufügt, der Unterthread die Sperre vor dem Beenden aufhebt und der Hauptthread eine Schleife durchläuft, um den Status der Sperre zu überprüfen. Der Code lautet wie folgt:
2. Der zweite Fehler ist der Vergleich von 2import thread class Hello: def __init__(self,content,lock): print content """ do something .... At the end,release the lock """ lock.release() def cs(): lock=thread.allocate_lock() lock.acquire() thread.start_new_thread(Hello, ("Hello World",lock)) while True: if not lock.locked(): break print "lock release" if __name__=='__main__': cs() import thread class Hello: def __init__(self,content,lock): print content """ do something .... At the end,release the lock """ lock.release() def cs(): lock=thread.allocate_lock() lock.acquire() thread.start_new_thread(Hello, ("Hello World",lock)) while True: if not lock.locked(): break print "lock release" if __name__=='__main__': cs()
self.source.send[data]
peError: 'builtin_function_or_method' object abmeldebar
self.source.send[data]
TypeError: Das Objekt „builtin_function_or_method“ ist abmeldebar
Die Hauptbedeutung besteht darin, dass integrierte Funktionen oder Methoden keine Subskripte haben können. Du hast es verstanden