zoukankan      html  css  js  c++  java
  • python实战--Http代理服务器

    打算好好深入研究下pytho的socket编程,那天看了这篇博文,http://www.apprk.com/archives/146,于是打算学习下,仿写了一下,发现写好还真不容易,中途出现很多问题,果真是看的容易,做起来难啊。

     源代码如下:

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


    我很失望的发现,报了个异常

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


    结果如下: 

    Hello World
    lock release
    

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

      self.source.send[data]
    TypeError: 'builtin_function_or_method' object is unsubscriptable


    主要是单词unsubscriptable不认识,呵呵,单词不认识,伤不起啊。

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






  • 相关阅读:
    angularjs中ng-repeat插入图片
    Torch not compiled with CUDA enabled
    ai 网格变换工具
    ai 网格变换工具
    最后的进入nms的shape数值是怎么来的
    问题import win32api windows下安装pycocotools
    问题、
    输入的图片size为什么是32的倍数,yolo各个模型层说明。upsample+route过程
    YOLO V3代码带注释-阅读笔记系列
    张量或维度表示数学理解思路
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3180301.html
Copyright © 2011-2022 走看看