Python實現搭建-簡單伺服器教程

来源:https://www.cnblogs.com/djdjdj123/archive/2023/04/18/17329903.html
-Advertisement-
Play Games

Python動態伺服器網頁(需要使用WSGI介面),基本實現步驟如下: 1.等待客戶端的鏈接,伺服器會收到一個http協議的請求數據報 2.利用正則表達式對這個請求數據報進行解析(請求方式、提取出文件的環境) 3.提取出文件的環境之後,利用截斷取片的方法將文件名轉化為模塊名稱 4.使用m = __i ...


Python動態伺服器網頁(需要使用WSGI介面),基本實現步驟如下:
1.等待客戶端的鏈接,伺服器會收到一個http協議的請求數據報
2.利用正則表達式對這個請求數據報進行解析(請求方式、提取出文件的環境)
3.提取出文件的環境之後,利用截斷取片的方法將文件名轉化為模塊名稱
4.使用m = __import__(),就可以得到返回值為m的模塊
5.創建一個env字典:其中包含的是請求方式及文件環境等各種的鍵值對
6.創建一個新的動態腳本,其中定義了application這個函數,必須包含env和start_response的參數(也是伺服器里的調用方法)
7.在這個動態腳本中定義狀態碼status和響應頭headers(註意是字典形式,如Content-Type)
8.然後再調用start_response(status,headers),但是要註意,這個函數在伺服器被定義
9.在動態腳本中編寫動態執行程式
10.m.appliction的返回值就是回應數據包的body,它的數據頭在start_response被整合
11.將數據頭與數據body拼接起來,然後發送給客戶端,就可顯示動態網頁

MyWebServer

import socket
import re
import sys
 
from multiprocessing import Process
from MyWebFramework import Application
 
# 設置靜態文件根目錄
HTML_ROOT_DIR = "./html"
WSGI_PYTHON_DIR = "./wsgipython"
 
class HTTPServer(object):
    """"""
    def __init__(self, application):
        """構造函數, application指的是框架的app"""
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.app = application
 
    def start(self):
        self.server_socket.listen(128)
        while True:
            client_socket, client_address = self.server_socket.accept()
            #print("[%s,%s]用戶連接上了" % (client_address[0],client_address[1]))
            print("[%s, %s]用戶連接上了" % client_address)
            handle_client_process = Process(target=self.handle_client, args=(client_socket,))
            handle_client_process.start()
            client_socket.close()
 
    def start_response(self, status, headers):
        """
         status = "200 OK"
    headers = [
        ("Content-Type", "text/plain")
    ]
    star
        """
        response_headers = "HTTP/1.1 " + status + "\r\n"
        for header in headers:
            response_headers += "%s: %s\r\n" % header
 
        self.response_headers = response_headers
 
    def handle_client(self, client_socket):
        """處理客戶端請求"""
        # 獲取客戶端請求數據
        request_data = client_socket.recv(1024)
        print("request data:", request_data)
        request_lines = request_data.splitlines()
        for line in request_lines:
            print(line)
 
        # 解析請求報文
        # 'GET / HTTP/1.1'
        request_start_line = request_lines[0]
        # 提取用戶請求的文件名
        print("*" * 10)
        print(request_start_line.decode("utf-8"))
        file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode("utf-8")).group(1)
        method = re.match(r"(\w+) +/[^ ]* ", request_start_line.decode("utf-8")).group(1)
 
        env = {
            "PATH_INFO": file_name,
            "METHOD": method
        }
        response_body = self.app(env, self.start_response)
        response = self.response_headers + "\r\n" + response_body
 
        # 向客戶端返迴響應數據
        client_socket.send(bytes(response, "utf-8"))
        # 關閉客戶端連接
        client_socket.close()
 
    def bind(self, port):
        self.server_socket.bind(("", port))
 
def main():
    sys.path.insert(1, WSGI_PYTHON_DIR)
    if len(sys.argv) < 2:
        sys.exit("python MyWebServer.py Module:app")
    # python MyWebServer.py  MyWebFrameWork:app
    module_name, app_name = sys.argv[1].split(":")
    # module_name = "MyWebFrameWork"
    # app_name = "app"
    m = __import__(module_name)
    app = getattr(m, app_name)
    http_server = HTTPServer(app)
    # http_server.set_port
    http_server.bind(8000)
    http_server.start()
 
if __name__ == "__main__":
    main()

MyWebFrameWork

import time
# from MyWebServer import HTTPServer
 
# 設置靜態文件根目錄
HTML_ROOT_DIR = "./html"
 
class Application(object):
    """框架的核心部分,也就是框架的主題程式,框架是通用的"""
    def __init__(self, urls):
        # 設置路由信息
        self.urls = urls
 
    def __call__(self, env, start_response):
        path = env.get("PATH_INFO", "/")
        # /static/index.html
        if path.startswith("/static"):
            # 要訪問靜態文件
            file_name = path[7:]
            # 打開文件,讀取內容
            try:
                file = open(HTML_ROOT_DIR + file_name, "rb")
            except IOError:
                # 代表未找到路由信息,404錯誤
                status = "404 Not Found"
                headers = []
                start_response(status, headers)
                return "not found"
            else:
                file_data = file.read()
                file.close()
 
                status = "200 OK"
                headers = []
                start_response(status, headers)
                return file_data.decode("utf-8")
 
        for url, handler in self.urls:
            #("/ctime", show_ctime)
            if path == url:
                return handler(env, start_response)
 
        # 代表未找到路由信息,404錯誤
        status = "404 Not Found"
        headers = []
        start_response(status, headers)
        return "not found"
 
def show_ctime(env, start_response):
    status = "200 OK"
    headers = [
        ("Content-Type", "text/plain")
    ]
    start_response(status, headers)
    return time.ctime()
 
def say_hello(env, start_response):
    status = "200 OK"
    headers = [
        ("Content-Type", "text/plain")
    ]
    start_response(status, headers)
    return "hello itcast"
 
def say_haha(env, start_response):
    status = "200 OK"
    headers = [
        ("Content-Type", "text/plain")
    ]
    start_response(status, headers)
    return "hello haha"
 
urls = [
            ("/", show_ctime),
            ("/ctime", show_ctime),
            ("/sayhello", say_hello),
            ("/sayhaha", say_haha),
        ]
app = Application(urls)
# if __name__ == "__main__":
#     urls = [
#             ("/", show_ctime),
#             ("/ctime", show_ctime),
#             ("/sayhello", say_hello),
#             ("/sayhaha", say_haha),
#         ]
#     app = Application(urls)
#     http_server = HTTPServer(app)
#     http_server.bind(8000)
#     http_server.start()

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Go語言流媒體開源項目 LAL 今天發佈了v0.35.4版本。 LAL 項目地址:https://github.com/q191201771/lal 老規矩,簡單介紹一下: ▦ 一. OBS支持RTMP H265推流 新出的標準,一般被稱為enhanced RTMP,OBS新版(29.1+版本,點我 ...
  • 什麼是冒泡排序 冒泡排序(Bubble Sort)也是一種簡單直觀的排序演算法。它重覆地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重覆地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢"浮"到數列的頂端 ...
  • 平時開發時的工作的話之主要負責寫代碼就行了,什麼發佈項目啊,好吧不是我們乾的事。在我們的瞭解中打包發佈項目應該不是一個困難的問題。 對,最簡單的方法就行使用直接使用maven插件打包,甚至我們都不需要知道他是怎麼實現的,插件能幫我們將項目打包為一個jar包,然後使用java -jar xx.jar就 ...
  • 使用第三方jar包,完成get/set操作 Lombok,結合特殊的註解,實現setter和getter的自動生成 導入jar包 使用插件Lombok 在類里import 即可使用 import lombok.AllArgsConstructor; import lombok.Data; impor ...
  • 本文介紹基於Python中ArcPy模塊,對大量長時間序列柵格遙感影像文件的每一個像元進行多時序平均值的求取。 在遙感應用中,我們經常需要對某一景遙感影像中的全部像元的像素值進行平均值求取——這一操作很好實現,基於ArcMap軟體或者簡單的Python代碼就可以實現;但有時候,我們會需要結合同一地區 ...
  • 前言 我們日常開發過程,會有一些定時任務的代碼來統計一些系統運行數據,但是我們應用有需要部署多個實例,傳統的通過配置文件來控制定時任務是否啟動又太過繁瑣,而且還經常出錯,導致一些異常數據的產生 網上有很多分散式鎖的實現方案,基於redis、zk、等有很多,但是我的就是一個用了mysql和mongo的 ...
  • 教程簡介 PHP語法吸收了C語言、Java和Perl的特點,易於學習,使用廣泛,主要適用於Web開發領域。PHP 獨特的語法混合了C、Java、Perl以及PHP自創的語法。它可以比CGI或者Perl更快速地執行動態網頁。用PHP做出的動態頁面與其他的編程語言相比,PHP是將程式嵌入到HTML(標準 ...
  • 教程簡介 EJB入門教程 - 從簡單的步驟瞭解EJB 3.0和3.1(Enterprise Java Bean)框架,從基本概念到高級概念,包括概述,環境設置,應用伺服器,容器,企業Bean,註釋,會話,無狀態會話,有狀態會話,消息驅動,實體Bean,持久性,遠程介面,查找,生命周期,介面,攔截器, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...