ホームページ >バックエンド開発 >Python チュートリアル >HTTPプロキシサーバー
最近、Pythonソケットプログラミングを深く勉強する予定なので、それを学んで真似するつもりですが、途中で多くの問題が表示され、見るのは簡単ですが、難しいことがわかりました。 do
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()
実際、プロキシサーバー自体は難しくありませんが、非常に簡単なので、ここではソースコードを詳しく説明しません。主に私が遭遇した問題について話します。
1: 元々、thread.start_new_thread の最初のパラメータが関数オブジェクトであることしか知らなかったのですが、上記のブログ投稿を見てびっくりしたので、すぐにテストしてみました。スレッドは
sys.Excepthook のエラーによって開始されました:
元の例外は:
パラメータがオブジェクトである可能性はありますか? 私は笑って、作者を少し軽蔑しました。それで、翌日、私はまだ諦めていなかったので、コードをダウンロードしてローカルで試してみましたが、すぐにそれが私であることに気づき、すぐにBaiduに行きました。
スレッド モジュールでは、メイン スレッドが子スレッドより先に終了すると、この例外がスローされることが判明したため、子スレッドを最初に終了させる必要があります。最も簡単な方法は、メイン スレッドを長時間スリープさせることです。どれくらい時間がかかるかわからないようですが、どうすれば解決できますか?
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()2. 2 番目のエラーは 2 を比較していますself.source.send[data]peError: 'builtin_function_or_method' object is unsubscriptable self.source.send[data]TypeError : 'builtin_function_or_method' オブジェクトは添字が付けられません主な意味は、組み込み関数またはメソッドには添字を付けることができないということです