科技知识动态:Http代理服务器

导读跟大家讲解下有关Http代理服务器,相信小伙伴们对这个话题应该也很关注吧,现在就为小伙伴们说说Http代理服务器,小编也收集到了有关Http代

跟大家讲解下有关Http代理服务器,相信小伙伴们对这个话题应该也很关注吧,现在就为小伙伴们说说Http代理服务器,小编也收集到了有关Http代理服务器的相关资料,希望大家看到了会喜欢。

最近打算好好深入研究下python的socket编程, 于是打算学习下,仿写了一下,发现写好还真不容易,中途出现很多问题,果真是看的容易,做起来难啊

import socketimport threadimport urlparseimport 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 socketimport threadimport urlparseimport selectBUFLEN=8192class 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: passif __name__=='__main__': s=Server('127.0.0.1',8080) s.start()

其实Http代理服务器本身不难,但写出来还是挺费事的,这里就不细说源代码了,很简单。主要说说,我遇到的问题。

一: 我本来只知道,thread.start_new_thread的第一个参数是函数对象,但当我看到上面的博文时,心里一愣,这样也可以,于是我迅速的测试了一下:

import thread class Hello: def __init__(self,content): print content def cs(): thread.start_new_thread(Hello, ("Hello World",)) if __name__=='__main__': cs()import threadclass Hello: def __init__(self,content): print contentdef cs(): thread.start_new_thread(Hello, ("Hello World",))if __name__=='__main__': cs()

Unhandled exception in thread started by Error in sys.excepthook: Original exception was:

Unhandled exception in thread started byError in sys.excepthook:

Original exception was:

一看,我说嘛,第一个参数怎么可以是对象,我呵呵一笑,稍微鄙视了一下作者。于是,我洗洗睡了,第二天,我还是不死心,于是把代码下下来,本地实验了一下,可以的,立马意识到是我2了,于是立马百度。

原来thread模块中,主线程如果比子线程先结束,就会抛出这个异常,所以我们必须让子线程先结束,最简单的方法就是让主线程sleep足够长的时间,至于多长时间,貌似不知道,那到底怎么解决呢?

比较好的解决办法就是,主线程给每个子线程都加一把锁,子线程在结束前将锁释放掉,主线程一直循环检查锁的状态。代码如下:

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()import threadclass 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()

二.第二个错误就是比较2的了

self.source.send[data]

peError: 'builtin_function_or_method' object is unsubscriptable

self.source.send[data]

TypeError: 'builtin_function_or_method' object is unsubscriptable

主要意思就是说,内置函数或方法无法拥有下标,你懂的

来源:php中文网

免责声明:本文由用户上传,如有侵权请联系删除!