python实战--Http代理服务器

转自:https://www.weidianyuedu.com/

最近打算好好深入研究下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('\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()
其实Http代理服务器本身不难,但写出来还是挺费事的,这里就不细说源代码了,很简单。主要说说,我遇到的问题。

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

import thread

class Hello:
def init(self,content):
print content

def cs():
thread.start_new_thread(Hello, (“Hello World”,))

if namemain’:
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 namemain’:
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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值