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('\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的第一个参数是函数对象,但当我看到上面的博文时,心里一愣,这样也可以,于是我迅速的测试了一下:
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。
python实战--Http代理服务器的更多相关文章
- zeromq 学习和python实战
参考文档: 官网 http://zeromq.org/ http://www.cnblogs.com/rainbowzc/p/3357594.html 原理解读 zeromq只是一层针对socke ...
- Python实战:美女图片下载器,海量图片任你下载
Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知识总结.希望大家能够快速入门并学习 ...
- Python实战:Python爬虫学习教程,获取电影排行榜
Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知识总结.希望大家能够快速入门并学习 ...
- python实战--数据结构二叉树
此文将讲述如何用python实战解决二叉树实验 前面已经讲述了python语言的基本用法,现在让我们实战一下具体明确python的用法 点击我进入python速成笔记 先看一下最终效果图: 首先我们要 ...
- 再一波Python实战项目列表
前言: 近几年Python可谓是大热啊,很多人都纷纷投入Python的学习中,以前我们实验楼总结过多篇Python实战项目列表,不但有用还有趣,最主要的是咱们实验楼不但有详细的开发教程,更有在线开发环 ...
- python实战:用70行代码写了一个山炮计算器!
python实战训练:用70行代码写了个山炮计算器! 好了...好了...各位因为我是三年级而发牢骚的各位伙伴们,我第一次为大家插播了python的基础实战训练.这个,我是想给,那些python基础一 ...
- python实战博客
2018-10-31 更新Logging日志记录以及异常捕获 感谢廖大教程.Python实战 直接在闲置的服务器上开发.阿里云Centos 6.8 64位. 1 搭建开发环境 Python 环境是Py ...
- python实战提升--1
#python实战提升 1. 如何在列表.字典.集合中根据条件筛选数据? python中for _ in range(10)与for i in range(10)有何区别 下划线表示 临时变量, 仅用 ...
- 原创:centos7.1下 ZooKeeper 集群安装配置+Python实战范例
centos7.1下 ZooKeeper 集群安装配置+Python实战范例 下载:http://apache.fayea.com/zookeeper/zookeeper-3.4.9/zookeepe ...
随机推荐
- linux中C的静态库和动态库分析
从开始学C语言写第一个"hello world"历程到现在,我依然困惑于到底这个程序完整的执行流程是什么样的.不过,现在我正在尝试一点一点的揭开它的面纱.现在,我尝试分析linux ...
- AOP和IOC理解
在百度上看到一篇很有意思的文章,是对AOP的一种解释,如下:(摘自:百度文库的 AOP和IOC最容易理解的说明(Spring知识小计)): IOC,依赖倒置的意思, 所谓依赖,从程序的角度看,就是比如 ...
- 文档学习 - UILabel - 属性详解
#import "ViewController.h" @implementation ViewController - (void)viewDidLoad { [super vie ...
- Aircrack-ng官方文档翻译[中英对照]---Airdecap-ng
Aircrack-ng官方文档翻译---Airdecap-ng Description[简介] With airdecap-ng you can decrypt WEP/WPA/WPA2 capt ...
- IP工具类——IpAddress.java
根据IP地址获取详细的地域信息,也可通过 http://whois.pconline.com.cn/ 获取地址信息. 源码如下:(点击下载 IpAddress.java) import java.i ...
- 关于MATLAB中的tic toc的问题
关于MATLAB中的tic toc的问题 其一) MATLAB实际单位时间计时函数的具体应用,在编写程序时,经常需要获知代码的执行实际时间,这就需要在程序中用到计时函数,matlab中提供了以下三种方 ...
- js template
http://garann.github.io/template-chooser/ http://www.gbin1.com/technology/javascript/20120917-javasc ...
- Java运算符(一)equals方法与“==”
超类Object的equals只是比较两者之间的引用对象是否相同,这一点跟操作符“==”是一样的. 在基本数据类型中,“==”用于比较两者之间的值(内容)是否相等. 在引用类型中,“==”用于比较两者 ...
- 怎么样删除eclipse已经记录svn的地址
eclipse-->window-->show view-->svn选项卡中选中要删除的svn链接,点击右键废弃即可. 1.
- [收藏转贴]struct探索·extern "C"含义探索 ·C++与C的混合编程·C 语言高效编程的几招
一.C/C++语言 struct深层探索 1.自然对界 struct是一种复合数据类型,其构成元素既可以是基本数据类型(如 int.long.float等)的变量,也可以是一些复合数据类型(如 arr ...