打算好好深入研究下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. 详解C/C++函数指针声明

    要理解一个C程序,仅仅理解组成该程序的符号是不够的.程序员还必须理解这些符号是如何组合成声明.表达式.语句和程序的. 我们先来看看下面的一个语句: 1 ( *( void(*)())0)(); 这是当 ...

  2. AFNetworking的原理与基本使用-b

    全称是AFNetworking 虽然运行效率没有ASI高,但是使用比ASI简单 是对NSURLConnection和NSURLSession的各自的一层包装 AFN的内部中的RunLoop AFN内部 ...

  3. 【BZOJ 3926】 [Zjoi2015]诸神眷顾的幻想乡 (广义SAM)

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 974  Solved: 573 Descriptio ...

  4. Navigation Drawer介绍

    在2013 google IO当天,Android团的更新了Support库,新版本(V13)的Support库中新加入了几个比较重要的功能. 添加 DrawerLayout 控件,支持创建  Nav ...

  5. Linux本地无法登录,远程却可以登录

    [root@oraserver ~]# vi /etc/pam.d/login 将以下内容注释掉: #session    required     /lib/security/pam_limits. ...

  6. 查找mysql数据文件存放路径

    show variables like 'datadir%'; show variables当前的会话,是系统参数 是静态 show global variables全局 show status是系统 ...

  7. Javascript 探路

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. bzoj1295

    考虑到这道题n,m都很小,我们考虑先穷举起点i 下面我们要做的是找出移走k个障碍后,点i所能到的最大距离 我们可以把这个问题转化为判定性问题 对于一对点i,j,如果他们之间存在一条路径,障碍数(包括起 ...

  9. POJ_3068_Shortest_pair_of_paths_(最小费用流)

    描述 http://poj.org/problem?id=3068 危险品:N个仓库由M条有向边连接,每条边都有一定费用.将两种危险品从0运到N-1,除了起点和终点外,危险品不能放在一起,也不能走相同 ...

  10. awk将普通文本转换成json文件

    script1: #!/bin/bash #Date:-- #Author:eivll0m awk -F"\t" -vq='"' '{ a[$]=a[$]?a[$]:$ ...