Porxy Server
本作业的基本要求可参考: https://blog.csdn.net/young_cr7/article/details/104703586
-
原理介绍
(1) POST请求一般用于向服务器发送数据,而代理服务器可将客户端发送的数据缓存。若存在历史数据则进行比对,两者一致则无需向服务器发送该数据(此处假设由客户端发送POST请求,经代理服务器到达服务器,是服务器获取数据的唯一方式)。两者不一致或不存在历史数据时,则由代理服务器通过POST请求方式向服务器发送数据,同时将该数据缓存。当发送数据成功时,则向客户端发送响应报文"OK"
(2) 接受POST请求的服务器可利用Python的flask进行编写
from flask import Flask, request app = Flask(__name__) @app.route('/simulator/gridConnect/', methods=['GET', 'POST']) def set_grid_connect(): recv_data = request.get_json() print(request) if recv_data: grid_connect = recv_data['grid_connected'] return "OK"
(3) 可借助Postman软件向代理服务器发送POST请求
-
Source code
from socket import *
import traceback
tcpSerSock = socket(AF_INET, SOCK_STREAM)
server_port = 22500
tcpSerSock.bind(('', server_port))
tcpSerSock.listen(1)
while True:
print('Ready to serve...')
tcpCliSock, addr = tcpSerSock.accept()
print('Received a connection from:', addr)
message = tcpCliSock.recv(1024).decode(encoding="utf-8")
print(message)
request_method = message.split()[0]
# Extract the filename from the given message
filename = message.split()[1].partition("//")[2].replace('/', '_').replace(':', '_')
print(filename)
fileExist = "false"
if request_method == "GET":
# 省略
elif request_method == "POST":
try:
post_data = ''.join(message[message.index('{') + 1:message.index('}')].split())
print(post_data)
f = open(filename, "r")
outputdata = f.read()
print(outputdata)
if post_data != outputdata:
raise ValueError
tcpCliSock.sendall("HTTP/1.1 200 OK\r\n".encode(encoding="utf-8"))
tcpCliSock.sendall("Content-Type:text/html\r\n".encode(encoding="utf-8"))
tcpCliSock.sendall("\r\nOK\r\n".encode(encoding="utf-8"))
print('Not modified')
except IOError:
print(traceback.format_exc())
tmpFile = open("./" + filename, "w")
tmpFile.writelines(post_data)
tmpFile.close()
c = socket(AF_INET, SOCK_STREAM)
host_address = message.split()[1].partition("//")[2].partition("/")[0].replace("www.", "", 1)
hostname = host_address.partition(":")[0]
host_port = int(host_address.partition(":")[2])
try:
c.connect((hostname, host_port))
old_url = message.split()[1]
new_url = ''.join(old_url.partition("//")[2].partition("/")[1:])
message = message.replace(old_url, new_url)
c.send(message.encode(encoding="utf-8"))
buff = c.recv(1024).decode(encoding="utf-8")
print(buff)
tcpCliSock.send("HTTP/1.1 200 OK\r\n".encode(encoding="utf-8"))
tcpCliSock.send("Content-Type:text/html\r\n".encode(encoding="utf-8"))
tcpCliSock.send("\r\nOK\r\n".encode(encoding="utf-8"))
except:
print("Illegal request")
tcpCliSock.close()
tcpSerSock.close()
-
客户端
向服务器发送grid_connected
数据(数据为json格式),响应报文为OK
-
代理服务器
(1) 代理服务器没有该数据的缓存时,向服务器发送POST请求
POST http://localhost:9000/simulator/gridConnect/ HTTP/1.1 Content-Type: application/json User-Agent: PostmanRuntime/7.22.0 Accept: */* Cache-Control: no-cache Postman-Token: 39ae1a6d-1547-4ce6-afbe-b29d2eff9a06 Host: localhost:9000 Accept-Encoding: gzip, deflate, br Content-Length: 35 Connection: keep-alive { "grid_connected": true } localhost_9000_simulator_gridConnect_ "grid_connected":true Traceback (most recent call last): File "D:/Pycharm-project/Computer Network/Socket/Proxy Server/proxyServer.py", line 61, in <module> f = open(filename, "r") FileNotFoundError: [Errno 2] No such file or directory: 'localhost_9000_simulator_gridConnect_' HTTP/1.0 200 OK
(2) 代理服务器有了该数据的缓存,当客户端发送数据与历史数据一致时,代理服务器打印
Not modified
,不再向服务器发送请求POST http://localhost:9000/simulator/gridConnect/ HTTP/1.1 Content-Type: application/json User-Agent: PostmanRuntime/7.22.0 Accept: */* Cache-Control: no-cache Postman-Token: 6347322c-7f21-4c82-9866-a71a7ace662d Host: localhost:9000 Accept-Encoding: gzip, deflate, br Content-Length: 35 Connection: keep-alive { "grid_connected": true } localhost_9000_simulator_gridConnect_ "grid_connected":true "grid_connected":true Not modified