簡單web伺服器_簡單Web伺服器-網遊伺服器
阿新 • • 發佈:2021-02-06
技術標籤:簡單web伺服器
可以動態根據使用者的輸入,傳送指定的內容的頁面
主體程式碼
#!/usr/bin/env python # encoding: utf-8 # @Time : 2019/10/10 11:57 AM # @Author : Li Xinjian # @File : 12_簡單Web伺服器_網遊伺服器.py """ 1、在類的初始化方法中配置當前的專案 {"2048": "./2048", "植物大戰殭屍": "zwdzjs-v1", ...} 2、給類增加一個初始化專案配置的方法 init_project() 2.1 顯示所有可以釋出的遊戲 選單 2.2 接收使用者的選擇 2.3 儲存使用者選擇的遊戲對應的本地目錄 3、更改Web伺服器開啟的檔案目錄 """ import socket from application import app import sys # 目標:封裝為類,用start()方法啟動伺服器 class WebServer(object): def __init__(self, port): # 1、匯入模組 # 2、建立套接字 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 3、設定地址重用 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 4、繫結埠 tcp_server_socket.bind(("", port)) # 5、設定監聽,讓套接字由主動變為變得接收 tcp_server_socket.listen(128) self.tcp_server_socket = tcp_server_socket # 儲存要釋出的專案的路徑 self.current_dir = "" self.project_dict = dict() self.project_dict["植物大戰殭屍-普通版"] = "zwdzjs-v1" self.project_dict["植物大戰殭屍-外掛版"] = "zwdzjs-v2" self.project_dict["保衛蘿蔔"] = "tafang" self.project_dict["2048"] = "2048" self.project_dict["讀心術"] = "dxs" # 呼叫初始化遊戲專案的方法 self.init_project() def init_project(self): # 2.1 顯示所有可以釋出的遊戲選單 # 取出字典的所有key,轉化為列表 keys_list = list(self.project_dict.keys()) # 遍歷顯示所有的key # enumerate()會為列表新增索引[(0, ), (1, ), ...] for index, game_name in enumerate(keys_list): print(index, game_name) # 2.2 接收使用者的選擇 sel_no = int(input("請選擇要釋出的遊戲序號:n")) # 2.3 儲存使用者選擇的遊戲對應的本地目錄 # 根據使用者的選擇,得到遊戲的名稱 key_name = keys_list[sel_no] # 列表 current_dir = self.project_dict[key_name] # print(current_dir) self.current_dir = current_dir def start(self): print("Web伺服器已經啟動...等待客戶端連線...") # 6、接受客戶端連線(定義函式request_handler()) while True: new_client_socket, ip_port = self.tcp_server_socket.accept() print('新客戶來了:{}'.format(str(ip_port))) self.request_handler(new_client_socket, ip_port) def request_handler(self, new_client_socket, ip_port): # 接收資訊,並做出響應 # 7、新的套接字接受客戶端傳送的請求報文 request_data = new_client_socket.recv(1024) # print(request_data) # 解析請求報文,返回響應報文 response_data = app.application(new_client_socket, self.current_dir, request_data, ip_port) # 10、傳送響應報文 new_client_socket.send(response_data) new_client_socket.close() def main(): # 主函式 """ 1、匯入sys模組 2、獲取系統傳遞到程式的引數 3、判斷引數格式是否正確 4、判斷埠號是否是一個數字 5、獲取埠號 6、在啟動Web伺服器的時候,使用指定的埠 """ # 2、獲取系統傳遞到程式的引數 params_list = sys.argv print(params_list) # 3、判斷引數格式是否正確 if len(params_list) != 2: print("啟動失敗:引數格式錯誤!正確格式:python3 xxx.py 埠號") return # 4、判斷埠號是否是一個數字 if not params_list[1].isdigit(): print("啟動失敗,埠號不是一個純數字!") return # 5、獲取埠號 port = int(params_list[1]) # 6、在啟動Web伺服器的時候,使用指定的埠 ws = WebServer(port) ws.start() if __name__ == '__main__': main()
app.py程式碼
#!/usr/bin/env python # encoding: utf-8 # @Time : 2019/10/10 9:21 AM # @Author : Li Xinjian # @File : app.py from application import utils def parse_request(new_client_socket, request_data, ip_port): # 返回請求的資源的路徑 # 8、判斷協議是否為空 # 如果傳送的為空,說明客戶端下線 if len(request_data) == 0: print('{}客戶端已經下線'.format(str(ip_port))) new_client_socket.close() return # 根據客戶端瀏覽器請求的資源路徑,返回請求資源 # 1)把請求協議解碼(直接傳遞過來的是二進位制),得到請求報文的請求行字串 request_text = request_data.decode() # 2) 得到請求行 # 1) 查詢第一個rn出現的位置 loc = request_text.find("rn") # 2) 擷取字串,從開頭擷取到rn出現的位置 request_line = request_text[:loc] print(request_line) # 3) 把請求按空格分割,得到三個部分,需要的是第二個 request_list = request_line.split(" ") # print(request_list) # 得到請求資源的路徑 file_path = request_list[1] # 如果直接開啟,返回index.html if file_path == "/": file_path = "/index.html" return file_path def application(new_client_socket, current_dir, request_data, ip_port): # 處理請求 # 返回資源的路徑 file_path = parse_request(new_client_socket, request_data, ip_port) # 資料夾路徑 + 請求的資源路徑 resource_path = current_dir + file_path # 響應主體 try: with open(resource_path, "rb") as file: # 把讀取的內容返回給客戶端 response_body = file.read() response_data = utils.create_http_response("200 OK", response_body) except Exception as e: # 如果不存在,返回提示的錯誤 response_body = "Not Found. {}".format(str(e)) response_body = response_body.encode() response_data = utils.create_http_response("404 Not Found", response_body) # response_body = "HelloWorld" return response_data
utils.py程式碼
#!/usr/bin/env python # encoding: utf-8 # @Time : 2019/10/10 10:18 AM # @Author : Li Xinjian # @File : utils.py.py def create_http_response(status, response_body): # 拼接報文 # 9、拼接響應報文 # 不為空,返回響應報文 # 響應行 response_line = "HTTP/1.1 {}rn".format(status) # 響應頭 response_head = "Server:Python20WS/2.1rn" response_head += "Content-Type: text/htmlrn" # 響應空行 response_blank = "rn" response_data = (response_line + response_head + response_blank).encode() + response_body return response_data
執行截圖