文章出處
文章列表
代理服務器是在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
文章列表
全站熱搜