python多任务、面向对象、命令行启动动态绑定端口号静态web服务器代码实现
生活随笔
收集整理的這篇文章主要介紹了
python多任务、面向对象、命令行启动动态绑定端口号静态web服务器代码实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、靜態web服務器-多任務
多任務web服務器:使用多線程,比進程更節省資源,支持多用戶同時訪問,可以同時處理多個客戶端請求
- 實現步驟
- 若客戶端與服務端建立連接,則創建子線程,使用子線程處理客戶端請求,防止主線程阻塞
- 將創建的子線程設置為守護主線程,防止主線程無法退出
實現代碼
import socket import threading def handle_client_request(comm_socket): # 處理客戶端請求recv_data = comm_socket.recv(4096) # 接收請求的二進制數據if len(recv_data) == 0:print('未獲取到請求數據!')comm_socket.close()returnrecv_content = recv_data.decode('utf-8') # 對二進制數據解碼print('獲取到的數據內容為:', recv_content)request_list = recv_content.split(" ", maxsplit=2) # 根據指定字符串空格進行分割,最大分割次數為2request_path = request_list[1] # 獲取請求資源路徑print('請求路徑為:', request_path)if request_path == "/": # 判斷請求的是否是根目錄,若是則返回首頁指定數據request_path = "/index.html"try:with open('C:/Users/username/Desktop/ubuntu' + request_path, 'rb') as file: # 動態打開指定文件file_data = file.read() # 讀取指定文件數據except Exception as e: # 請求異常,資源不存在,返回指定404錯誤數據with open('C:/Users/username/Desktop/ubuntu/error.html', 'rb') as file: # 打開指定錯誤文件error_data = file.read() # 讀取指定錯誤數據response_line = "HTTP/1.1 404 Not Found!!\r\n" # 響應行response_header = "Server: PWS1.0 服務器名稱及版本……\r\n" # 響應頭response_body = error_data # 響應體response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body # 拼接響應報文comm_socket.send(response_data) # 發送數據給瀏覽器else:response_line = "HTTP/1.1 200 OK # 成功!!\r\n"response_header = "Server: PWS1.0 # 服務器名稱版本!\r\n"response_body = file_dataresponse_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodycomm_socket.send(response_data)finally:comm_socket.close() # 關閉服務于客戶端的套接字def main():server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 創建TCP服務端套接字server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 設置端口號復用,程序退出端口號立即釋放server_socket.bind(("", 9000)) # 綁定端口號server_socket.listen(128) # 設置監聽while True:comm_socket, ip_port = server_socket.accept() # 等待接受客戶端連接請求thread = threading.Thread(target=handle_client_request, args=(comm_socket,)) # 若客戶端和服務器連接成功,創建子線程thread.setDaemon(True) # 設置守護主線程thread.start() # 啟動子線程執行對應任務if __name__ == '__main__':main()輸出如下
獲取到的數據內容為: GET /index.html HTTP/1.1 Host: 127.0.0.1:9000 Connection: keep-alive Cache-Control: max-age=0 sec-ch-ua: "Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,;q=0.8,application/signed-exchange;v=b3;q=0.9 Sec-Fetch-Site: none Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Cookie: csrftoken=1wb7v0r0BQuokJCxRS4JAO2XApvrHXFP90t2PiYb0mz7AwWS0NoKTi0zNaIjOfTl; Hm_lvt_18f619820855042bca58b32408f44de7=1658219884請求路徑為: /index.html瀏覽器響應如下?
二、靜態web服務器-面向對象?
- 實現步驟
- 把提供服務的web服務器抽象為一個類
- 提供web服務器初始化方法,在方法中創建socket對象
- 提供一個開啟web服務器的方法,讓web服務器處理客戶端請求操作
實現代碼
import socket import threading class HttpWebServer(object): # 定義web服務器類,將提供服務的web服務器抽象為一個類def __init__(self): # 初始化服務端套接字server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 創建TCP套接字server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 設置端口復用,程序退出端口號立即釋放server_socket.bind(("", 9000)) # 綁定端口號server_socket.listen(128) # 設置監聽self.server_socket = server_socket@staticmethoddef handle_client_request(comm_socket):recv_data = comm_socket.recv(4096) # 接收請求的二進制數據if len(recv_data) == 0:print('未獲取到請求數據!')comm_socket.close()returnrecv_content = recv_data.decode('utf-8') # 對二進制數據解碼print('獲取到的數據內容為:', recv_content)request_list = recv_content.split(" ", maxsplit=2) # 根據指定字符串空格進行分割,最大分割次數為2request_path = request_list[1] # 獲取請求資源路徑print('請求路徑為:', request_path)if request_path == "/": # 判斷請求的是否是根目錄,若是則返回首頁指定數據request_path = "/index.html"try:with open('C:/Users/熊世強/Desktop/ubuntu' + request_path, 'rb') as file: # 動態打開指定文件file_data = file.read() # 讀取指定文件數據except Exception as e: # 請求異常,資源不存在,返回指定404錯誤數據with open('C:/Users/熊世強/Desktop/ubuntu/error.html', 'rb') as file: # 打開指定錯誤文件error_data = file.read() # 讀取指定錯誤數據response_line = "HTTP/1.1 404 Not Found!!\r\n" # 響應行response_header = "Server: PWS1.0 服務器名稱及版本……\r\n" # 響應頭response_body = error_data # 響應體response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body # 拼接響應報文comm_socket.send(response_data) # 發送數據給瀏覽器else:response_line = "HTTP/1.1 200 OK # 成功!!\r\n"response_header = "Server: PWS1.0 # 服務器名稱版本!\r\n"response_body = file_dataresponse_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodycomm_socket.send(response_data)finally:comm_socket.close() # 關閉服務于客戶端的套接字def start(self): # 啟動web服務器while True:comm_socket, ip_port = self.server_socket.accept() # 等待接收客戶端連接請求thread = threading.Thread(target=self.handle_client_request, args=(comm_socket,)) # 若客戶端和服務器建立連接,則創建子線程thread.setDaemon(True) # 設置守護子線程thread.start() # 啟動子線程執行對應任務def main(): # 程序入口函數webServer = HttpWebServer() # 創建web服務器對象webServer.start() # 啟動web服務器進行工作if __name__ == '__main__':main()輸出如下
獲取到的數據內容為: GET /index.html HTTP/1.1 Host: 127.0.0.1:9000 Connection: keep-alive Cache-Control: max-age=0 sec-ch-ua: "Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,;q=0.8,application/signed-exchange;v=b3;q=0.9 Sec-Fetch-Site: none Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Cookie: csrftoken=1wb7v0r0BQuokJCxRS4JAO2XApvrHXFP90t2PiYb0mz7AwWS0NoKTi0zNaIjOfTl; Hm_lvt_18f619820855042bca58b32408f44de7=1658219884請求路徑為: /index.html瀏覽器響應如下
?三、靜態web服務器-命令行啟動動態綁定端口號
- 實現步驟
- 獲取執行python程序的終端命令行參數
- 判斷參數類型,設置端口號必須是整型
- 為web服務器類的初始化方法添加一個端口號參數,用于綁定端口號
實現代碼
import socket import threading import sys class HttpWebServer(object): # 定義web服務器類,將提供服務的web服務器抽象為一個類def __init__(self, port): # 初始化服務端套接字,添加端口號參數server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 創建TCP套接字server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 設置端口復用,程序退出端口號立即釋放server_socket.bind(("", port)) # 綁定端口號server_socket.listen(128) # 設置監聽self.server_socket = server_socket@staticmethoddef handle_client_request(comm_socket): # 處理客戶端請求recv_data = comm_socket.recv(4096) # 接收請求的二進制數據if len(recv_data) == 0:print('未獲取到請求數據!')comm_socket.close()returnrecv_content = recv_data.decode('utf-8') # 對二進制數據解碼print('獲取到的數據內容為:', recv_content)request_list = recv_content.split(" ", maxsplit=2) # 根據指定字符串空格進行分割,最大分割次數為2request_path = request_list[1] # 獲取請求資源路徑print('請求路徑為:', request_path)if request_path == "/": # 判斷請求的是否是根目錄,若是則返回首頁指定數據request_path = "/index.html"try:with open('C:/Users/username/Desktop/ubuntu' + request_path, 'rb') as file: # 動態打開指定文件file_data = file.read() # 讀取指定文件數據except Exception as e: # 請求異常,資源不存在,返回指定404錯誤數據with open('C:/Users/username/Desktop/ubuntu/error.html', 'rb') as file: # 打開指定錯誤文件error_data = file.read() # 讀取指定錯誤數據response_line = "HTTP/1.1 404 Not Found!!\r\n" # 響應行response_header = "Server: PWS1.0 服務器名稱及版本……\r\n" # 響應頭response_body = error_data # 響應體response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body # 拼接響應報文comm_socket.send(response_data) # 發送數據給瀏覽器else:response_line = "HTTP/1.1 200 OK # 成功!!\r\n"response_header = "Server: PWS1.0 # 服務器名稱版本!\r\n"response_body = file_dataresponse_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodycomm_socket.send(response_data)finally:comm_socket.close() # 關閉服務于客戶端的套接字def start(self): # 啟動web服務器while True:comm_socket, ip_port = self.server_socket.accept() # 等待接收客戶端連接請求thread = threading.Thread(target=self.handle_client_request, args=(comm_socket,)) # 若客戶端和服務器建立連接,則創建子線程thread.setDaemon(True) # 設置守護子線程thread.start() # 啟動子線程執行對應任務def main(): # 程序入口函數print('命令行輸入的參數為:', sys.argv)if len(sys.argv) != 2: # 判斷命令行參數個數是否為2print("請執行格式為[ python3 xx.py 9000 ] 的命令")returnif not sys.argv[1].isdigit(): # 判斷字符串是否為數字組成,必須為整型print("請執行格式為[ python3 xx.py 9000 ]的命令")returnport = int(sys.argv[1]) # 獲取終端命令行參數web_server = HttpWebServer(port)web_server.start()if __name__ == '__main__':main()命令行執行
?瀏覽器響應如下?
?學習導航:http://xqnav.top/
總結
以上是生活随笔為你收集整理的python多任务、面向对象、命令行启动动态绑定端口号静态web服务器代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lisp型材库_基于AutoLISP的A
- 下一篇: C#导出Word总结