1. 程式人生 > >python實現一個簡單的http伺服器

python實現一個簡單的http伺服器

1. HTTP伺服器的實現

實現一個http伺服器說白了就是實現一個監聽程式,當客戶端發來對應的http請求時,能夠解析請求,並且返回對應的資源給客戶端,客戶端解析顯示到瀏覽器上。這裡我使用python實現一個最簡單的http伺服器。

1.1初始化

定義一個初始化方法,建立套接字,繫結地址,監聽埠,cnt用來統計客戶端請求數量。

def init(self):
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.
bind(("",80)) self.server_socket.listen(100) self.cnt = 0

1.2 啟動服務

def start(self):
        # print("cnt = %d"%self.cnt)
        # 主程序阻塞,等待客戶端傳送請求
        client_socket, client_address = self.server_socket.accept()
        self.cnt += 1
        print("connected from[%s, %s]" % client_address)
# 主程序啟動一個子程序處理客戶端請求 start_client_process = Process(target=self.client_server, args=(client_socket,client_address)) start_client_process.start() # 關閉主程序的套接字 client_socket.close()

1.3 請求處理函式

子程序處理請求,這裡為了簡化,僅僅區分了請求png檔案和其他檔案。

    def client_server(self,client_socket,
client_addr): request_data = client_socket.recv(1024) # 列印日誌 self.log(request_data) # 構造響應資料 response_start_line = "HTTP/1.1 200 OK\r\n" response_headers = "Server: My server\r\n" # 如果請求png圖片,那麼傳送本地的一張圖片給客戶端 if request_data.decode().find("1.png") > 0: filename = "1.png" with open(filename, 'rb+') as f: body = f.read() f.close() client_socket.send(body) # 其他請求,傳送一個html檔案給客戶端 else: filename = "1.html" with open(filename, encoding='utf-8') as f: body = f.read() f.close() response = response_start_line + response_headers +"\r\n" + body client_socket.send(bytes(response,"utf-8")) client_socket.close()

1.4 列印日誌

加了一個日誌列印方法,記錄請求的時間和內容

 def log(self, data):
        now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        with open("log.txt",'a+') as f:
            # f.write(now_time)
            f.write("\n%s\n%s" %(now_time, data))

完整的程式碼如下:

import socket
import datetime
from multiprocessing import Process
class webserver:
    def init(self):
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.bind(("",80))
        self.server_socket.listen(100)
        self.cnt = 0
    def start(self):
        print("cnt = %d"%self.cnt)
        client_socket, client_address = self.server_socket.accept()
        self.cnt += 1
        print("connected from[%s, %s]" % client_address)
        start_client_process = Process(target=self.client_server, args=(client_socket,client_address))
        start_client_process.start()
        client_socket.close()
    def client_server(self,client_socket, client_addr):
        request_data = client_socket.recv(1024)
        # 列印日誌
        self.log(request_data)
        # 構造響應資料
        response_start_line = "HTTP/1.1 200 OK\r\n"
        response_headers = "Server: My server\r\n"
        if request_data.decode().find("1.png") > 0:
            filename = "1.png"
            with open(filename, 'rb+') as f:
                body = f.read()
                f.close()
            client_socket.send(body) 
        else:
            filename = "1.html"
            with open(filename, encoding='utf-8') as f:
                body = f.read()
                f.close()
            response = response_start_line + response_headers +"\r\n" + body 
            client_socket.send(bytes(response,"utf-8"))    
        client_socket.close()
    def main(self):
        self.init()
        while True:
            self.start()
    def log(self, data):
        now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        with open("log.txt",'a+') as f:
            f.write("\n%s\n%s" %(now_time, data))

if __name__ == '__main__':
    res = webserver()
    res.main()

2. 執行結果

執行程式,然後開啟瀏覽器,在瀏覽器中輸入127.0.0.1,就可以看到輸出結果。如果開啟chrome的network,可以看到瀏覽器傳送了三個請求。
在這裡插入圖片描述

開啟errlog可以看到,有三條瀏覽記錄

在這裡插入圖片描述