科技知識動態: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中文網

免責聲明:本文由用戶上傳,如有侵權請聯系刪除!