其中static是静态文件目录,application.py是TCP连接监听和工作线程处理收发数据,request.py是解析http请求,response.py是封装发送数据模块,runserver.py是服务器启动模块
具体代码如下。
application.py
import socket
import threading
from response import HttpResponse
from request import HttpRequest
# WSGI服务器
class WSGIServer():
def __init__(self, host='localhost', port=8080, connectSize=100):
'''
:param port: 服务器的端口号
:param connectSize: 默认的并发数量
'''
self.__host = host
self.__port = port
self.__connectSize = connectSize
pass
def startServer(self):
'''
服务启动主程序
:return:
'''
server = None
try:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((self.__host, self.__port))
server.listen(self.__connectSize)
while True:
print("======服务器启动成功:http://" + self.__host + ":" + str(self.__port))
clientConn, clientAddr = server.accept() # 等待客户端请求
# 启动独立的线程,处理每一次用户请求
wt = WorkThread(clientConn, clientAddr)
wt.start()
pass
except socket.gaierror as g:
print(g)
finally:
if server:
server.close()
pass
pass
class WorkThread(threading.Thread):
def __init__(self, connection, addr, bufferSize=8096):
threading.Thread.__init__(self)
self.__connection = connection
self.__addr = addr
self.__bufferSize = bufferSize
pass
def run(self):
receiveMsg = self.__connection.recv(self.__bufferSize)
receiveMsg = receiveMsg.decode("utf-8")
print(receiveMsg)
request = HttpRequest()
params = request.parseRequest(receiveMsg)
responseText = ""
response = HttpResponse()
if params['Accept'].find('text/html') >=0:
url = 'templates/index.html'
if params['url'] == "/":
url = 'templates/index.html'
else:
url = 'templates' + params['url']
if params['url'] == '/main.html':
if params.get('dataparams').get('userName') != 'zhangsan':
url = 'templates/index.html'
responseText = response.responseHeader('text/html', 200) + "\n" + response.responseBodyText(url)
pass
pass
responseText = response.responseHeader('text/html', 200) + "\n" + response.responseBodyText(url)
self.__connection.send(responseText.encode("utf-8"))
pass
elif params['Accept'].find('image/') >= 0:
url = params['url']
self.__connection.send(response.responseHeader('image/', 200).encode("utf-8"))
self.__connection.send("\n".encode("utf-8"))
self.__connection.send(response.responseBodyBinary(url[1:]))
pass
print(responseText)
self.__connection.close()
pass
pass
request.py
class HttpRequest():
def parseRequest(self, requestText):
params = {}
lineArray = requestText.split('\r\n')
row = 1
isBody = False
bodyText = ""
for line in lineArray:
if row == 1 :
array = line.split(' ')
params['method'] = array[0]
params['url'] = array[1]
params['httptype'] = array[2]
row += 1
elif line.strip() == "":
isBody = True
elif not isBody:
array = line.split(':')
params[array[0]] = line[len(array[0])+2:]
pass
elif isBody:
bodyText += line
pass
params['body'] = bodyText
dataParams = {}
bodyText = bodyText.strip()
if params.get('Content-Type') == 'application/x-www-form-urlencoded' and params['method'] == 'POST':
array = bodyText.split('&')
for data in array:
keyvalue = data.split("=")
dataParams[keyvalue[0]] = keyvalue[1]
pass
pass
params['dataparams'] = dataParams
return params
pass
pass
response.py
class HttpResponse():
def responseHeader(self, contentType, ressponseCode):
header = "http/1.1 200 OK\r\n"
if contentType == 'text/html':
header += "Content-Type: text/html\r\n" + \
"X-Ua-Compatible: IE=Edge,chrome=1\r\n"
elif contentType == "image/":
header += "Content-Type: image/png\r\n" + \
"X-Ua-Compatible: IE=Edge,chrome=1\r\n"
return header
pass
def responseBodyText(self, url):
body = ""
with open(url, 'r') as fp:
body = fp.read()
return body
pass
def responseBodyBinary(self, url):
body = b""
with open(url, 'rb') as fp:
body = fp.read()
return body
pass
runserver.py
from application import WSGIServer
if __name__ == '__main__':
# 创建服务器对象
wsgiServer = WSGIServer()
wsgiServer.startServer()
pass
index.html
Title
Hello, my WSGI server!
main.html
Title
System main page!
运行效果