1. 程式人生 > >web靜態伺服器

web靜態伺服器

import socket
import re
import gevent
from gevent import monkey
import sys
# 打補丁
monkey.patch_all()


# 封裝的web伺服器類
class HttpWebServer(object):
    def __init__(self, port):
        # 建立tcp服務端套接字
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 設定socket選項,立即釋放埠
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 繫結埠號 tcp_server_socket.bind(("", port)) # 設定監聽 tcp_server_socket.listen(128) # 建立物件提供socket屬性 self.tcp_server_socket = tcp_server_socket # 啟動伺服器 def start(self)
: # 迴圈接收客戶端的連線請求 while True: service_client_socket, ip_port = self.tcp_server_socket.accept() # 開闢協程並執行對應的任務 gevent.spawn(self.handle_client_request, service_client_socket) # 不需要加上join,因為我們的程序不會退出 # g1.join() # 處理客戶端的請求
@staticmethod def handle_client_request(service_client_socket): # 獲取客戶端的請求報文資料 client_request_data = service_client_socket.recv(4096) print(client_request_data) # GET /index2.html HTTP/1.1xxxxxxx client_request_conent = client_request_data.decode("utf-8") # 通過正則查詢請求的資源路徑 match_obj = re.search("/\S*", client_request_conent) if not match_obj: print("訪問路徑有誤") service_client_socket.close() return # 獲取匹配結果 request_path = match_obj.group() print(request_path) if request_path == "/": # 如果使用者沒有指定資源路徑那麼預設訪問的資料是首頁的資料 request_path = "/index.html" # 讀取指定檔案資料 # 使用rb的原因是瀏覽器也有可能請求的是圖片 try: with open("static" + request_path, "rb") as file: # 讀取檔案資料 file_data = file.read() except Exception as e: # 準備響應報文資料 # 響應行 response_line = "HTTP/1.1 404 Not Found\r\n" # 響應頭 response_header = "Server: PWS1.0\r\nContent-Type: text/html;charset=utf-8\r\n" # 響應體 -> 開啟一個404html資料把資料給瀏覽器 response_body = "<h1>非常抱歉,您當前訪問的網頁已經不存在了</h1>".encode("utf-8") # 匹配響應報文資料 response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 傳送響應報文資料 service_client_socket.send(response_data) else: # 準備響應報文資料 # 響應行 response_line = "HTTP/1.1 200 OK\r\n" # 響應頭 response_header = "Server: PWS1.0\r\nContent-Type: text/html;charset=utf-8\r\n" # 響應體 response_body = file_data # 匹配響應報文資料 response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 傳送響應報文資料 service_client_socket.send(response_data) finally: service_client_socket.close() # 主函式 def main(): print(sys.argv) if len(sys.argv) != 2: print("啟動命令如下: python3 xxx.py 9090") return if not sys.argv[1].isdigit(): print("啟動命令如下: python3 xxx.py 9090") return port = int(sys.argv[1]) print(port) server = HttpWebServer(port) server.start() if __name__ == '__main__': main()