打算好好深入研究下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代理服务器的更多相关文章

  1. zeromq 学习和python实战

    参考文档: 官网 http://zeromq.org/ http://www.cnblogs.com/rainbowzc/p/3357594.html   原理解读 zeromq只是一层针对socke ...

  2. Python实战:美女图片下载器,海量图片任你下载

    Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知识总结.希望大家能够快速入门并学习 ...

  3. Python实战:Python爬虫学习教程,获取电影排行榜

    Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知识总结.希望大家能够快速入门并学习 ...

  4. python实战--数据结构二叉树

    此文将讲述如何用python实战解决二叉树实验 前面已经讲述了python语言的基本用法,现在让我们实战一下具体明确python的用法 点击我进入python速成笔记 先看一下最终效果图: 首先我们要 ...

  5. 再一波Python实战项目列表

    前言: 近几年Python可谓是大热啊,很多人都纷纷投入Python的学习中,以前我们实验楼总结过多篇Python实战项目列表,不但有用还有趣,最主要的是咱们实验楼不但有详细的开发教程,更有在线开发环 ...

  6. python实战:用70行代码写了一个山炮计算器!

    python实战训练:用70行代码写了个山炮计算器! 好了...好了...各位因为我是三年级而发牢骚的各位伙伴们,我第一次为大家插播了python的基础实战训练.这个,我是想给,那些python基础一 ...

  7. python实战博客

    2018-10-31 更新Logging日志记录以及异常捕获 感谢廖大教程.Python实战 直接在闲置的服务器上开发.阿里云Centos 6.8 64位. 1 搭建开发环境 Python 环境是Py ...

  8. python实战提升--1

    #python实战提升 1. 如何在列表.字典.集合中根据条件筛选数据? python中for _ in range(10)与for i in range(10)有何区别 下划线表示 临时变量, 仅用 ...

  9. 原创:centos7.1下 ZooKeeper 集群安装配置+Python实战范例

    centos7.1下 ZooKeeper 集群安装配置+Python实战范例 下载:http://apache.fayea.com/zookeeper/zookeeper-3.4.9/zookeepe ...

随机推荐

  1. Custom template tags and filters

    Code layout Custom template tags and filters must live inside a Django app. If they relate to an exi ...

  2. NSString NSMutableString copy mutableCopy retain weak strong整合

    copy retain assign的差别在于对象属性的set方法 NSString 与 NSMutableString NSString是不可变字符串对象,这句话的意思,结合代码: #import ...

  3. POJ 2002 Squares 哈希

    题目链接: http://poj.org/problem?id=2002 #include <stdio.h> #include <string.h> ; struct Has ...

  4. Android源码中的FLAG为何使用16进制

    1.在阅读源码的时候经常发现有一些标志属性使用一些位操作来判断是否具有该标志,增加标志或者去除标志. 比如View.java中的 /** * This view does not want keyst ...

  5. /etc/passwd 与 /etc/shadow

    /etc/passwd是用户数据库,其中的域给出了用户名.加密口令和用户的其他信息. /etc/shadow是在安装了影子(shadow)口令软件的系统上的影子口令文件.影子口令文件将/etc/pas ...

  6. Python Web 性能和压力测试 multi-mechanize

    http://www.aikaiyuan.com/5318.html 对Web服务做Performance & Load测试,最常见的工具有Apache Benchmark俗称ab和商用工具L ...

  7. 李洪强iOS开发Swift篇—07_函数

    李洪强iOS开发Swift篇—07_函数 一.函数的定义 (1)函数的定义格式 1 func 函数名(形参列表) -> 返回值类型 { 2 // 函数体... 3 4 } (2)形参列表的格式 ...

  8. SVN服务器及客户端的使用

    Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上了,下载地址:http://s ...

  9. 使用IAR6.1调试LPCXpresso-cn

    由于Manly公司驱动兼容性问题,下载破解版的IAR6.1 使用. http://blog.sina.com.cn/s/blog_48bde2b20101e6v0.html 然后使用IAR打开示例wo ...

  10. java常用重构优化总结--自己亲身体验

    代码重构  6大原则:    单一职责原则(一个类最好最好只有一种行为动机,太多承担职责会导致耦合度太高).    开放封闭原则(功能可以扩展,但是不可以内部修改).    依赖倒转原则(应该依赖抽象 ...