Web動(dòng)態(tài)服務(wù)器-1
#coding=utf-8
import socket
import sys
from multiprocessing import Process
import re
class WSGIServer(object):
addressFamily = socket.AF_INET
socketType = socket.SOCK_STREAM
requestQueueSize = 5
def __init__(self, serverAddress):
#創(chuàng)建一個(gè)tcp套接字
self.listenSocket = socket.socket(self.addressFamily,self.socketType)
#允許重復(fù)使用上次的套接字綁定的port
self.listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#綁定
self.listenSocket.bind(serverAddress)
#變?yōu)楸粍?dòng),并制定隊(duì)列的長(zhǎng)度
self.listenSocket.listen(self.requestQueueSize)
self.servrName = "localhost"
self.serverPort = serverAddress[1]
def serveForever(self):
'循環(huán)運(yùn)行web服務(wù)器,等待客戶端的鏈接并為客戶端服務(wù)'
while True:
#等待新客戶端到來(lái)
self.clientSocket, client_address = self.listenSocket.accept()
#方法2,多進(jìn)程服務(wù)器,并發(fā)服務(wù)器于多個(gè)客戶端
newClientProcess = Process(target = self.handleRequest)
newClientProcess.start()
#因?yàn)閯?chuàng)建的新進(jìn)程中,會(huì)對(duì)這個(gè)套接字+1,所以需要在主進(jìn)程中減去依次,即調(diào)用一次close
self.clientSocket.close()
def setApp(self, application):
'設(shè)置此WSGI服務(wù)器調(diào)用的應(yīng)用程序入口函數(shù)'
self.application = application
def handleRequest(self):
'用一個(gè)新的進(jìn)程,為一個(gè)客戶端進(jìn)行服務(wù)'
self.recvData = self.clientSocket.recv(2014)
requestHeaderLines = self.recvData.splitlines()
for line in requestHeaderLines:
print(line)
httpRequestMethodLine = requestHeaderLines[0]
getFileName = re.match("[^/]+(/[^ ]*)", httpRequestMethodLine).group(1)
print("file name is ===>%s"%getFileName) #for test
if getFileName[-3:] != ".py":
if getFileName == '/':
getFileName = documentRoot + "/index.html"
else:
getFileName = documentRoot + getFileName
print("file name is ===2>%s"%getFileName) #for test
try:
f = open(getFileName)
except IOError:
responseHeaderLines = "HTTP/1.1 404 not found\r\n"
responseHeaderLines += "\r\n"
responseBody = "====sorry ,file not found===="
else:
responseHeaderLines = "HTTP/1.1 200 OK\r\n"
responseHeaderLines += "\r\n"
responseBody = f.read()
f.close()
finally:
response = responseHeaderLines + responseBody
self.clientSocket.send(response)
self.clientSocket.close()
else:
#根據(jù)接收到的請(qǐng)求頭構(gòu)造環(huán)境變量字典
env = {}
#調(diào)用應(yīng)用的相應(yīng)方法,完成動(dòng)態(tài)數(shù)據(jù)的獲取
bodyContent = self.application(env, self.startResponse)
#組織數(shù)據(jù)發(fā)送給客戶端
self.finishResponse(bodyContent)
def startResponse(self, status, response_headers):
serverHeaders = [
('Date', 'Tue, 31 Mar 2016 10:11:12 GMT'),
('Server', 'WSGIServer 0.2'),
]
self.headers_set = [status, response_headers + serverHeaders]
def finishResponse(self, bodyContent):
try:
status, response_headers = self.headers_set
#response的第一行
response = 'HTTP/1.1 {status}\r\n'.format(status=status)
#response的其他頭信息
for header in response_headers:
response += '{0}: {1}\r\n'.format(*header)
#添加一個(gè)換行,用來(lái)和body進(jìn)行分開
response += '\r\n'
#添加發(fā)送的數(shù)據(jù)
for data in bodyContent:
response += data
self.clientSocket.send(response)
finally:
self.clientSocket.close()
#設(shè)定服務(wù)器的端口
serverAddr = (HOST, PORT) = '', 8888
#設(shè)置服務(wù)器靜態(tài)資源的路徑
documentRoot = './html'
#設(shè)置服務(wù)器動(dòng)態(tài)資源的路徑
pythonRoot = './wsgiPy'
def makeServer(serverAddr, application):
server = WSGIServer(serverAddr)
server.setApp(application)
return server
def main():
if len(sys.argv) < 2:
sys.exit('請(qǐng)按照要求,指定模塊名稱:應(yīng)用名稱,例如 module:callable')
#獲取module:callable
appPath = sys.argv[1]
#根據(jù)冒號(hào)切割為module和callable
module, application = appPath.split(':')
#添加路徑套sys.path
sys.path.insert(0, pythonRoot)
#動(dòng)態(tài)導(dǎo)入module變量中指定的模塊
module = __import__(module)
#獲取module變量中指定的模塊的,application變量指定的屬性
application = getattr(module, application)
httpd = makeServer(serverAddr, application)
print('WSGIServer: Serving HTTP on port %d ...\n'%PORT)
httpd.serveForever()
if __name__ == '__main__':
main()
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。