python實現一個簡單的http伺服器
阿新 • • 發佈:2019-01-01
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可以看到,有三條瀏覽記錄