代理服务器是在client和server之间的一个服务器,一般起到缓存的作用,所以也叫缓存服务器。比如:

A ----(HTTP)----》 B ----(HTTP)----》 C

其中A是客户端,C是服务器端,那么B就是proxy server了,是代理服务器,也是缓存服务器:当A发起请求时要求获得C上的一个文件,需要先经过B,B在自己的文件系统中寻找是否有A所请求的文件,如果有,就发给A,完成一次响应;如果没有,则在B上创建新的HTTP请求,发送到C,并将C的响应缓存到文件中,同时回发给A。

只要代理服务器B上存在A所需要的文件,就不必劳烦C重新发送响应,一定程度上减轻C的压力,同时减少响应时间。

下面我们用socket编程来实现一个简单的代理服务器,功能为:

访问 localhost:8899/helloworld.html 格式的url时,若helloworld.html与proxy server在同一目录下,那么返回这个文件,否则报错

访问 localhost:8899/www.baidu.com 格式的url时,从proxy server的文件系统中查找www.baidu.com的缓存文件,若存在则返还;若不存在则向baidu.com发起HTTP请求,将得到的响应缓存并发给客户端。

其中发送的HTTP请求,由tcp socket实现。

#coding:utf-8
from socket import * # 创建socket,绑定到端口,开始监听
tcpSerPort = 8899
tcpSerSock = socket(AF_INET, SOCK_STREAM) # Prepare a server socket
tcpSerSock.bind(('', tcpSerPort))
tcpSerSock.listen(5) while True:
# 开始从客户端接收请求
print 'Ready to serve...'
tcpCliSock, addr = tcpSerSock.accept()
print 'Received a connection from: ', addr
message = tcpCliSock.recv(4096) # 从请求中解析出filename
print message.split()[1]
filename = message.split()[1].partition("/")[2]
fileExist = "false"
filetouse = "/" + filename
try:
# 检查缓存中是否存在该文件
f = open(filetouse[1:], "r")
outputdata = f.readlines()
fileExist = "true"
print 'File Exists!' # 缓存中存在该文件,把它向客户端发送
tcpCliSock.send("HTTP/1.0 200 OK\r\n\r\n") for i in range(0, len(outputdata)):
tcpCliSock.send(outputdata[i])
print 'Read from cache' # 缓存中不存在该文件,异常处理
except IOError:
print 'File Exist: ', fileExist
if fileExist == "false":
# 在代理服务器上创建一个tcp socket
print 'Creating socket on proxyserver'
c = socket(AF_INET, SOCK_STREAM) hostn = filename.replace("www.", "", 1)
print 'Host Name: ', hostn
try:
# 连接到远程服务器80端口
c.connect((hostn, 80))
print 'Socket connected to port 80 of the host' # 在代理服务器上缓存请求的文件
fileobj = c.makefile('r', 0)
#拼凑http get请求的请求行。注意格式为: "请求方法 URI HTTP版本",空格不能省略!
fileobj.write("GET " + "http://" + filename + " HTTP/1.0\n\n") # Read the response into buffer
buff = fileobj.readlines() # Create a new file in the cache for the requested file.
# Also send the response in the buffer to client socket
# and the corresponding file in the cache
tmpFile = open("./" + filename,"wb")
for i in range(0, len(buff)):
tmpFile.write(buff[i])
tcpCliSock.send(buff[i]) except:
print "Illegal request" else:
# HTTP response message for file not found
# Do stuff here
print 'File Not Found...Stupid Andy'
a = 2
# Close the client and the server sockets
tcpCliSock.close()
# Fill in start.
tcpSerSock.close()
# Fill in end.

ref:《计算机网络:自顶向下方法》第二章 套接字编程作业4

简易代理服务器之python实现的更多相关文章

  1. 简易坦克大战python版

      #! /usr/bin/env python # -*- coding:utf8 -*- ''' *author:wasua *purpose:学习python语言,其中的类以及pygame应用 ...

  2. 高逼格利器之Python闭包与装饰器

    生活在魔都的小明,终于攒够了首付,在魔都郊区买了一套房子:有一天,小明踩了狗屎,中了一注彩票,得到了20w,小明很是欢喜,于是想干脆用这20万来装修房子吧(decoration): 整个装修过程,小明 ...

  3. Python实现简易HTTP服务器

    一.Python3 搭建简易HTTP服务器 python -m http.server 浏览器访问:http://localhost:8000 Python3 cgiserver python -m  ...

  4. Python代码样例列表

    扫描左上角二维码,关注公众账号 数字货币量化投资,回复“1279”,获取以下600个Python经典例子源码 ├─algorithm│       Python用户推荐系统曼哈顿算法实现.py│    ...

  5. python之----------字符编码具体原理

    1.内存和硬盘都是用来存储的. CPU:速度快 硬盘:永久保存 2.文本编辑器存取文件的原理(nodepad++,pycharm,word) 打开编辑器就可以启动一个进程,是在内存中的,所以在编辑器编 ...

  6. python全栈开发-Day6 字符编码

    python全栈开发-Day6 字符编码 一 .了解字符编码的知识储备 一 .计算机基础知识 二 .文本编辑器存取文件的原理(nodepad++,pycharm,word) #1.打开编辑器就打开了启 ...

  7. 第三篇:Python字符编码

    一 .了解字符编码的知识储备 1计算机基础知识 1.2文本编辑器存取文件的原理(nodepat++,Pycharm,word) #.打开编辑器就打开了启动了一个进程,是在内存中的,所以,用编辑器编写的 ...

  8. Python系列之 - 字符编码问题

    1.内存和硬盘都是用来存储的. CPU:速度快 硬盘:永久保存 2.文本编辑器存取文件的原理(nodepad++,pycharm,word) 打开编辑器就可以启动一个进程,是在内存中的,所以在编辑器编 ...

  9. Python实现数据库一键导出为Excel表格

    依赖 Python2711 xlwt MySQLdb 数据库相关 连接 获取字段信息 获取数据 Excel基础 workbook sheet 案例 封装 封装之后 测试结果 总结 数据库数据导出为ex ...

随机推荐

  1. SQL注入9种绕过WAF方法

    SQL注入9种绕过WAF方法 0x01前言 WAF区别于常规 防火墙 是因为WAF能够过滤特定Web应用程序的内容,而常规防火墙则充当服务器之间的防御门.通过检查HTTP的流量,它可以防御Web应用安 ...

  2. CSS中background样式的repeat和no-repeat

    自http://blog.sina.com.cn/s/blog_98eef7830101cv8t.html获取的知识,特此感谢. <!DOCTYPE html> <html lang ...

  3. opencv2 直方图之calchist函数使用(转)

    OpenCV提供了calcHist函数来计算图像直方图. 其中C++的函数原型如下:void calcHist(const Mat* arrays, int narrays, const int* c ...

  4. Hdu1255 覆盖的面积

    覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  5. wireshark 根据域名筛选

    应该去掉引号

  6. discuz 删除垃圾帖子

    有时候如果你的论坛被垃圾帖子占满后,会发现使用后台的删除功能还是有些慢, 我们需要先备份自己需要的帖子,然后进行下面的操作: 具体删除帖子的步骤,就是清空数据库里面的两张数据库表:pre_forum_ ...

  7. springboot创建maven多模块项目

    SpringBoot创建maven多模块项目 项目结构 该项目名称为springboot-maven-multi,由springboot-maven-multi.user-dao.user-domai ...

  8. swiper.js的使用

    点击api文档地址, (1)图片轮播banner <script src="js/jquery-2.1.4.min.js"></script> <sc ...

  9. 树dp...吧 ZOJ 3949

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5568 Edge to the Root Time Limit: 1 Secon ...

  10. HDU 1452 欧拉定理

    让你求$2004^x$所有因子之和,因子之和函数是积性函数$\sigma(n)=\sum_{d|n}d=\prod_{i=0}^{m}(\sum_{j=0}^{k_i}{P_i^{j}})$可用二项式 ...