最近在學習python,分享一下多進程的服務器
需要了解的一些知識(若這些不懂代碼不好理解)
- 多進程 ,進程是系統進行資源分配和調度的單元,創建多進程能夠實現多個任務同時進行的目的。python中實現多進程要運用到python標準庫multiprocessing
- socket 模塊,socket 套接字,類似一種載體,進程間通信的一種方式,服務器和客戶端之間主要用socket進行數據傳輸。
- multiprocessing 模塊用法,導入模塊from multiprocessing import Process ,創建一個Process對象,每個process對象都是一個進程,
p = Processing(target= 函數, args=(函數的參數, ) )
開啓這個進程:
p.start() - 正則表達式,從瀏覽器的請求報文中刪選出用戶訪問的資源名稱,運用到python的標準庫 re模塊 。
# re正則模塊
import re
# 導入多進程的模塊
import multiprocessing
# 導入套接字模塊
import socket
class Server(object):
'''創建一個具體的服務器類'''
def __init__(self, server_address):
# 創建套接字連接
self.listen_soket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 防止服務器強制斷開,端口無法使用的問題
self.listen_soket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 綁定ip和端口 sever_address是傳入的參數
self.listen_soket.bind(server_address)
# 把套接字變爲監聽狀態,監聽瀏覽器的來訪
self.listen_soket.listen(128)
def handle_client(self,cli_socket):
# 瀏覽器發送來的請求信息
recv_data = cli_socket.recv(1024).decode('utf-8')
# 請求報文 ,對報文進行按行分割,請求報文是一行一行的信息GET / HTTP/1.1
request_lines = recv_data.splitlines()
# request_lines是一個列表,列表的第一個元素代表第一行報文,裏面有請求資源的信息
# 利用正則表達式匹配出請求的資源路徑,r'[^/]+([^ ]*)' 意思是:r代表原始字符格式,
# 匹配 至少一個非/字符,/開始就是請求資源名稱,路徑名稱後面跟着的是空格
file_name = re.match(r'[^/]+([^ ]*)', request_lines[0]).group(1)
# index.html是我文件夾裏的html文件,默認訪問這個文件
if file_name == '/':
file_name = ROOT + '/index.html'
else:
file_name = ROOT + file_name
try:
f = open(file_name, 'rb')
except:
# 沒找到文件資源後,響應報文的內容
response_lines = 'HTTP1.1/ 404 NOT FOUND\r\n' + '\r\n'
response_body = '<h1>there is no file </h1>'
else:
# 讀取訪問的文件內容作爲報文體,加上報文頭
file_content = f.read()
response_lines = 'HTTP1.1/ 200 OK\r\n' + '\r\n'
response_body = file_content
finally:
# 用套接字傳遞給瀏覽器
cli_socket.send(response_lines).encode('utf-8')
cli_socket.send(response_body)
cli_socket.close()
def server_forver(self):
while True:
# 循環可以讓多個瀏覽器同時訪問,listen_socket監聽來來訪的瀏覽器,
# accept返回的是元組,來訪瀏覽器的ip地址和端口
cli_socket, cli_address = self.listen_soket.accept()
# 創建多進程 multiprocessing中的Process類創建對象
p = multiprocessing.Process(target=handle_client, args=(cli_socket,))
# 開始運行進程
p.start()
cli_socket.close()
# ROOT爲網頁文件的根目錄,html是一個文件加的名稱
ROOT = './html'
# IP地址 和 端口,默認是本機ip
SERVER_ADD = (HOST, PORT) = '',7878
def main():
# 創建服務器對象
mysever = Server(SERVER_ADD)
# 調用服務器對象的方法
mysever.server_forver()
if __name__ == '__main__':
main()