视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Http代理服务器
2020-11-27 14:28:09 责编:小采
文档


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

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('
')
 if index >0:
 break
 #firstLine,self.request=header.split('
',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
" %(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('
')
 if index >0:
 break
 #firstLine,self.request=header.split('
',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
" %(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()

其实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 thread
class Hello:
 def __init__(self,content):
 print content
def 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 by
Error 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 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()

二.第二个错误就是比较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

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

下载本文
显示全文
专题