简易代理服务器之python实现

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

代理服务器是在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

目录
相关文章
|
4天前
|
网络协议 数据格式 Python
Python进阶---HTTP协议和Web服务器
Python进阶---HTTP协议和Web服务器
17 4
|
4天前
|
网络协议 Python
在python中利用TCP协议编写简单网络通信程序,要求服务器端和客户端进行信息互传。 - 蓝易云
在这个示例中,服务器端创建一个socket并监听本地的12345端口。当客户端连接后,服务器发送一条欢迎消息,然后关闭连接。客户端创建一个socket,连接到服务器,接收消息,然后关闭连接。
56 0
|
7天前
|
SQL 存储 数据库
两个Python脚本轻松解决ETL工作:统计多个服务器下所有数据表信息
两个Python脚本轻松解决ETL工作:统计多个服务器下所有数据表信息
|
7天前
|
SQL 存储 数据库
两个Python脚本轻松解决ETL工作:统计多个服务器下所有数据表信息(1)
两个Python脚本轻松解决ETL工作:统计多个服务器下所有数据表信息(1)
|
10天前
|
Oracle Java 关系型数据库
【服务器】python通过JDBC连接到位于Linux远程服务器上的Oracle数据库
【服务器】python通过JDBC连接到位于Linux远程服务器上的Oracle数据库
18 6
|
10天前
|
机器学习/深度学习 数据挖掘 Python
使用Python实现简单的Web服务器
使用Python内置的http.server模块,本文演示了创建基本Web服务器的步骤。通过编写简单的代码,实现响应GET请求并返回“Hello, World!”。此外,还展示了如何扩展服务器功能,处理不同URL路径,如根路径和/about路径,并实现404错误页面。这个基础教程为理解HTTP服务器原理和Python网络编程入门提供了帮助。对于复杂Web应用,建议使用Flask或Django等高级框架。
|
10天前
|
Linux 网络安全 开发工具
【超详细!超多图!】【代码管理】Python微信公众号开发(3)- 服务器代码上传Github
【超详细!超多图!】【代码管理】Python微信公众号开发(3)- 服务器代码上传Github
40 0
|
网络协议 Python
Python网络编程——静态Web服务器实现
可以为发出请求的浏览器提供静态文档的程序。即所访问的页面是静态的,页面中的内容不会发生变化。HTTP协议(HyperText Transfer Protocol,超文本传输协议)使用于从www服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本,还确定传输文档中的哪一部分,以及那部分内容首先显示(如文本先于图形)等
15134 14
|
3天前
|
存储 算法 安全
Python编程实验六:面向对象应用
Python编程实验六:面向对象应用
20 1
|
3天前
|
Python
Python编程作业五:面向对象编程
Python编程作业五:面向对象编程
19 1