0
点赞
收藏
分享

微信扫一扫

Python实现伪源站服务器

古月无语 2023-01-06 阅读 116


         学习python是因为当时学习的C语言实现一个东西太难了,做一个图形界面又丑又难看,而且还很难写。python高度封装,简洁,第三方库也超多,像列表这种东西用起来真是太爽了,对于字符串简直无所不能,所以还是那句话人生苦短,我用python。当时对语言的性能并没有太多的认知,写代码大多也就一两百行的样子,内存、CPU都是可以随意挥霍的东西。python的性能还是比不上C语言,但是开发速度还是很可以的,大家都说一种很折中的go语言,开发速度与执行效率介于python和C语言之间,以后有时间在学校吧。

         通过看源码webbech和tinyhttpd熟悉语言怎么处理http请求,那么用python语言就是太容易实现了。下面我用python实现一个多线程的伪源站服务器,利用python提供的SocketServer,每来一个连接,我就返回2500000字节的文件。源码如下:

         

#! /usr/bin/python2.7
#coding:utf-8


import SocketServer
import datetime
#import os
import sys # sys.argc sys.argv
import time # for sleep


gHttpbody=""

def CreateHttpBodyData():
sLineBody = "test-data-body "
for i in range(4):
sLineBody += sLineBody
sLineBody += "\n"

sRspBody = ""
for i in range(10000):
sLine = "__%05d__" % (i)
sRspBody += sLine + sLineBody

return sRspBody


class Myserver(SocketServer.BaseRequestHandler):
def RcvInit(self):
self.sHeadInfo = ""
self.sReqLine = ""
self.sClientIP = ""
self.sClientPort = 0


def RcvHeadInfo(self):
sTempData = ""
while True:
receiveData = self.request.recv(4096)
if receiveData is None:
print "no receive data"
return False

if len(receiveData) == 0:
print "RcvHeadInfo : receive empty data"
return False

sTempData = sTempData + receiveData
iPos = sTempData.find("\r\n\r\n")
if iPos >= 0:
break

if len(sTempData) > 1024:
print "error, receive data too long:",len(sTempData)
return False


self.sHeadInfo = sTempData[0:iPos]
print self.sHeadInfo

return True

def GetReqLine(self):
aHeadList = self.sHeadInfo.split("\r\n")
sMethod = "GET "
for sHeadLine in aHeadList:
iPos = sHeadLine.find(sMethod)
if iPos >= 0:
iPos = iPos + len(sMethod)
self.sReqLine = sHeadLine[iPos:]
self.sReqLine = self.sReqLine.strip()
break

return self.sReqLine

def GetHeader(self, head_name):
head_begin = self.sHeadInfo.find(head_name)
if head_begin < 0:
return ""
head_begin += len(head_name)
head_end = self.sHeadInfo.find("\r\n", head_begin)
if head_end < 0:
print "can not find head_end"
return ""

head_val = self.sHeadInfo[head_begin:head_end]

return head_val
def DoRsp304(self, sReqLine):
aHeaders = []
aHeaders.append(("Server", "python-test"))

if(sReqLine.find("close=0") < 0):
aHeaders.append(("Connection", "close"))
aHeaders.append(("TestHttp", "python Server"))
aHeaders.append(("author", "vaynedu-ying"))
aHeaders.append(("Last-Modified", "Fri, 28 Oct 6666 66:66:66 GMT"))
aHeaders.append(("Content-Length", "0"))

sSendHeader = "HTTP/1.1 304 xxx\r\n"
for (sHeadName, sHeadValue) in aHeaders:
sSendHeader += sHeadName + ": " + sHeadValue + "\r\n"

self.request.sendall(sSendHeader)
self.request.sendall("\r\n") #结束信息

print sSendHeader
return

def GetChipList(self, sReqLine, iChipNum=10):
global gHttpbody
sRspBody = gHttpbody
iBodylen = len(sRspBody)
iChipLen = iBodylen/iChipNum
asChipList = []
for i in range(iChipNum-1):
sChip = sRspBody[iChipLen*i : iChipLen*(i+1)]
asChipList.append(sChip)

sChip = sRspBody[iChipLen*(iChipNum-1): ]
asChipList.append(sChip)

return (asChipList, iBodylen)


def DoRspBody(self, sReqLine):
global gHttpbody
aHeaders = []
aHeaders.append(("Server","python-test"))

if(sReqLine.find("close=0") < 0):
aHeaders.append(("Connection", "close"))
aHeaders.append(("TestHttp", "python Server"))
aHeaders.append(("author", "vaynedu-ying"))
aHeaders.append(("Content-type", "video/mp2t"))
#aHeaders.append(("Last-Modified", "Fri, 2 Oct 2017 00:00:00 GMT"))
aHeaders.append(("Last-Modified", "Fri, 28 Oct 2016 12:35:18 GMT"))


(asChipList, iBodylen) = self.GetChipList(sReqLine, 10)
sLenValue = str(iBodylen)
#print sLenValue
aHeaders.append(("Content-Length", sLenValue))
sSendHeader = "HTTP/1.1 200 OK\r\n"
for(sHeadName, sHeadValue) in aHeaders:
sSendHeader += sHeadName + ": " + sHeadValue + "\r\n"

self.request.sendall(sSendHeader)
self.request.sendall("\r\n")
print sSendHeader

iNum = 0
for sChip in asChipList:
self.request.sendall(sChip)
time.sleep(0.01)

return


def do_GET(self, sReqLine):
NowTime = datetime.datetime.now()
sTime = NowTime.strftime("%Y-%m-%d_%H-%M-%S")

print sTime, " GET ", sReqLine

sModified = self.GetHeader("If-Modified-Since: ")
if (sModified != ""):
self.DoRsp304(sReqLine)
return

sNodeMatch = self.GetHeader("If-None-Match: ")
if (sNodeMatch != ""):
self.DoRsp304(sReqLine)
return

self.DoRspBody(sReqLine)

return



def setup(self):
(sIP, iPort) = self.request.getpeername()
self.RcvInit()
self.sClientIP = sIP
self.sClientPort = iPort
# print "client ip : ", sIP, "client port: ", iPort

def handle(self):
bIsHeadRcv = self.RcvHeadInfo()
if bIsHeadRcv == False:
self.request.close()
return

sReqLine = self.GetReqLine()

if sReqLine == "":
self.request.close()
return

self.do_GET(sReqLine)

time.sleep(5)

self.request.close()
return

def finish(self):
print "client ip : ", self.sClientIP, "client port: ", self.sClientPort, " is close"


if __name__ == '__main__':
if len(sys.argv) >= 3:
sLocalIP = sys.argv[1]
sLocalPort = sys.argv[2]
else:
sLocalIP = r"localhost"
sLocalPort = "8080"


gHttpbody = CreateHttpBodyData()
print "test http body length: ", len(gHttpbody)

server = SocketServer.ThreadingTCPServer((sLocalIP, int(sLocalPort)), Myserver)
print "Starting server, use <Ctrl + C> to stop"
server.serve_forever()



服务端效果

Python实现伪源站服务器_服务器


客户端效果

Python实现伪源站服务器_Line_02


最后在说一下,原来从服务器上下载的文件都是按照上一次修改时间来计算的,看来我之前理解错误了。

Python实现伪源站服务器_python_03


如果有什么问题,欢迎大家讨论指正!!!


举报

相关推荐

0 条评论