Python本地搭建靜態(tài)Web服務(wù)器的實(shí)現(xiàn)
靜態(tài)Web服務(wù)器-返回固定頁面數(shù)據(jù)
學(xué)習(xí)目標(biāo)
能夠?qū)懗鼋M裝固定頁面數(shù)據(jù)的響應(yīng)報(bào)文
1. 開發(fā)自己的靜態(tài)Web服務(wù)器
實(shí)現(xiàn)步驟:
- 編寫一個(gè)TCP服務(wù)端程序
- 獲取瀏覽器發(fā)送的http請(qǐng)求報(bào)文數(shù)據(jù)
- 讀取固定頁面數(shù)據(jù),把頁面數(shù)據(jù)組裝成HTTP響應(yīng)報(bào)文數(shù)據(jù)發(fā)送給瀏覽器。
- HTTP響應(yīng)報(bào)文數(shù)據(jù)發(fā)送完成以后,關(guān)閉服務(wù)于客戶端的套接字。
2. 靜態(tài)Web服務(wù)器-返回固定頁面數(shù)據(jù)的示例代碼
import socket # 判斷是否是主模塊的代碼 if __name__ == '__main__': # 創(chuàng)建tcp服務(wù)端套接字 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 設(shè)置端口號(hào)復(fù)用,程序退出端口號(hào)立即釋放 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 綁定端口號(hào) tcp_server_socket.bind(("", 8000)) # 設(shè)置監(jiān)聽 tcp_server_socket.listen(128) # 循環(huán)等待接受客戶端的連接請(qǐng)求 while True: # 等待接受客戶端的連接請(qǐng)求 new_socket, ip_port = tcp_server_socket.accept() # 代碼執(zhí)行到此,說明連接建立成功 # 接收客戶端的請(qǐng)求信息 recv_data = new_socket.recv(4096) print(recv_data) # 打開文件讀取文件中的數(shù)據(jù) with open("static/index.html", "r") as file: # 這里的file表示打開文件的對(duì)象 file_data = file.read() # 提示: with open 關(guān)閉文件這步操作不用程序員來完成,系統(tǒng)幫我們來完成 # 響應(yīng)行 response_line = "HTTP/1.1 200 OK\r\n" # 響應(yīng)頭 response_header = "Server: PWS/1.0\r\n" # 響應(yīng)體 response_body = file_data # 把數(shù)據(jù)封裝成http 響應(yīng)報(bào)文格式的數(shù)據(jù) response = response_line + response_header + "\r\n" + response_body # 把字符串編碼成二進(jìn)制 response_data = response.encode("utf-8") # 發(fā)送給瀏覽器的響應(yīng)報(bào)文數(shù)據(jù) new_socket.send(response_data) # 關(guān)閉服務(wù)于客戶端的套接字 new_socket.close()
3. 小結(jié)
編寫一個(gè)TCP服務(wù)端程序
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 循環(huán)接受客戶端的連接請(qǐng)求 while True: conn_socket, ip_port = tcp_server_socket.accept()
獲取瀏覽器發(fā)送的http請(qǐng)求報(bào)文數(shù)據(jù)
client_request_data = conn_socket.recv(4096)
讀取固定頁面數(shù)據(jù),把頁面數(shù)據(jù)組裝成HTTP響應(yīng)報(bào)文數(shù)據(jù)發(fā)送給瀏覽器。
response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body conn_socket.send(response_data)
HTTP響應(yīng)報(bào)文數(shù)據(jù)發(fā)送完成以后,關(guān)閉服務(wù)于客戶端的套接字。
conn_socket.close()
靜態(tài)Web服務(wù)器-返回指定頁面數(shù)據(jù)
學(xué)習(xí)目標(biāo)
能夠?qū)懗鼋M裝指定頁面數(shù)據(jù)的響應(yīng)報(bào)文
1. 靜態(tài)Web服務(wù)器的問題
目前的Web服務(wù)器,不管用戶訪問什么頁面,返回的都是固定頁面的數(shù)據(jù),接下來需要根據(jù)用戶的請(qǐng)求返回指定頁面的數(shù)據(jù)
返回指定頁面數(shù)據(jù)的實(shí)現(xiàn)步驟:
- 獲取用戶請(qǐng)求資源的路徑
- 根據(jù)請(qǐng)求資源的路徑,讀取指定文件的數(shù)據(jù)
- 組裝指定文件數(shù)據(jù)的響應(yīng)報(bào)文,發(fā)送給瀏覽器
- 判斷請(qǐng)求的文件在服務(wù)端不存在,組裝404狀態(tài)的響應(yīng)報(bào)文,發(fā)送給瀏覽器
2. 靜態(tài)Web服務(wù)器-返回指定頁面數(shù)據(jù)的示例代碼
import socket import os def main(): # 創(chuàng)建tcp服務(wù)端套接字 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 設(shè)置端口號(hào)復(fù)用,程序退出端口號(hào)立即釋放 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 綁定端口號(hào) tcp_server_socket.bind(("", 8000)) # 設(shè)置監(jiān)聽 tcp_server_socket.listen(128) # 循環(huán)等待接受客戶端的連接請(qǐng)求 while True: # 等待接受客戶端的連接請(qǐng)求 new_socket, ip_port = tcp_server_socket.accept() # 代碼執(zhí)行到此,說明連接建立成功 # 接收客戶端的請(qǐng)求信息 recv_data = new_socket.recv(4096) # 判斷接收的數(shù)據(jù)長度是否為0 if len(recv_data) == 0: new_socket.close() return # 對(duì)二進(jìn)制數(shù)據(jù)進(jìn)行解碼 recv_content = recv_data.decode("utf-8") print(recv_content) # 對(duì)數(shù)據(jù)按照空格進(jìn)行分割 request_list = recv_content.split(" ", maxsplit=2) # 獲取請(qǐng)求的資源路徑 request_path = request_list[1] print(request_path) # 判斷請(qǐng)求的是否是根目錄,如果是根目錄設(shè)置返回的信息 if request_path == "/": request_path = "/index.html" # 1. os.path.exits # os.path.exists("static/" + request_path) # 2. try-except # 打開文件讀取文件中的數(shù)據(jù), 提示:這里使用rb模式,兼容打開圖片文件 with open("static" + request_path, "rb") as file: # 這里的file表示打開文件的對(duì)象 file_data = file.read() # 提示: with open 關(guān)閉文件這步操作不用程序員來完成,系統(tǒng)幫我們來完成 # 代碼執(zhí)行到此,說明文件存在,返回200狀態(tài)信息 # 響應(yīng)行 response_line = "HTTP/1.1 200 OK\r\n" # 響應(yīng)頭 response_header = "Server: PWS/1.0\r\n" # 響應(yīng)體 response_body = file_data # 把數(shù)據(jù)封裝成http 響應(yīng)報(bào)文格式的數(shù)據(jù) response = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 發(fā)送給瀏覽器的響應(yīng)報(bào)文數(shù)據(jù) new_socket.send(response) # 關(guān)閉服務(wù)于客戶端的套接字 new_socket.close() # 判斷是否是主模塊的代碼 if __name__ == '__main__': main()
3. 小結(jié)
獲取用戶請(qǐng)求資源的路徑
request_list = client_request_conent.split(" ", maxsplit=2) request_path = request_list[1]
根據(jù)請(qǐng)求資源的路徑,讀取請(qǐng)求指定文件的數(shù)據(jù)
with open("static" + request_path, "rb") as file: file_data = file.read()
組裝指定文件數(shù)據(jù)的響應(yīng)報(bào)文,發(fā)送給瀏覽器
response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body conn_socket.send(response_data)
判斷請(qǐng)求的文件在服務(wù)端不存在,組裝404狀態(tài)的響應(yīng)報(bào)文,發(fā)送給瀏覽器
try: # 打開指定文件,代碼省略... except Exception as e: conn_socket.send(404響應(yīng)報(bào)文數(shù)據(jù))
靜態(tài)Web服務(wù)器-返回404頁面數(shù)據(jù)
import socket import os def main(): # 創(chuàng)建tcp服務(wù)端套接字 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 設(shè)置端口號(hào)復(fù)用,程序退出端口號(hào)立即釋放 tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 綁定端口號(hào) tcp_server_socket.bind(("", 8000)) # 設(shè)置監(jiān)聽 tcp_server_socket.listen(128) # 循環(huán)等待接受客戶端的連接請(qǐng)求 while True: # 等待接受客戶端的連接請(qǐng)求 new_socket, ip_port = tcp_server_socket.accept() # 代碼執(zhí)行到此,說明連接建立成功 # 接收客戶端的請(qǐng)求信息 recv_data = new_socket.recv(4096) # 判斷接收的數(shù)據(jù)長度是否為0 if len(recv_data) == 0: new_socket.close() return # 對(duì)二進(jìn)制數(shù)據(jù)進(jìn)行解碼 recv_content = recv_data.decode("utf-8") print(recv_content) # 對(duì)數(shù)據(jù)按照空格進(jìn)行分割 request_list = recv_content.split(" ", maxsplit=2) # 獲取請(qǐng)求的資源路徑 request_path = request_list[1] print(request_path) # 判斷請(qǐng)求的是否是根目錄,如果是根目錄設(shè)置返回的信息 if request_path == "/": request_path = "/index.html" # 1. os.path.exits # os.path.exists("static/" + request_path) # 2. try-except try: # 打開文件讀取文件中的數(shù)據(jù), 提示:這里使用rb模式,兼容打開圖片文件 with open("static" + request_path, "rb") as file: # 這里的file表示打開文件的對(duì)象 file_data = file.read() # 提示: with open 關(guān)閉文件這步操作不用程序員來完成,系統(tǒng)幫我們來完成 except Exception as e: # 代碼執(zhí)行到此,說明沒有請(qǐng)求的該文件,返回404狀態(tài)信息 # 響應(yīng)行 response_line = "HTTP/1.1 404 Not Found\r\n" # 響應(yīng)頭 response_header = "Server: PWS/1.0\r\n" # 讀取404頁面數(shù)據(jù) with open("static/error.html", "rb") as file: file_data = file.read() # 響應(yīng)體 response_body = file_data # 把數(shù)據(jù)封裝成http 響應(yīng)報(bào)文格式的數(shù)據(jù) response = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 發(fā)送給瀏覽器的響應(yīng)報(bào)文數(shù)據(jù) new_socket.send(response) else: # 代碼執(zhí)行到此,說明文件存在,返回200狀態(tài)信息 # 響應(yīng)行 response_line = "HTTP/1.1 200 OK\r\n" # 響應(yīng)頭 response_header = "Server: PWS/1.0\r\n" # 響應(yīng)體 response_body = file_data # 把數(shù)據(jù)封裝成http 響應(yīng)報(bào)文格式的數(shù)據(jù) response = (response_line + response_header + "\r\n").encode("utf-8") + response_body # 發(fā)送給瀏覽器的響應(yīng)報(bào)文數(shù)據(jù) new_socket.send(response) finally: # 關(guān)閉服務(wù)于客戶端的套接字 new_socket.close() # 判斷是否是主模塊的代碼 if __name__ == '__main__': main()
到此這篇關(guān)于Python本地搭建靜態(tài)Web服務(wù)器的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python本地搭建靜態(tài)Web服務(wù)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python必學(xué)知識(shí)之文件操作(建議收藏)
python中對(duì)文件、文件夾(文件操作函數(shù))的操作需要涉及到os模塊和shutil模塊。下面這篇文章主要給大家介紹了關(guān)于python必學(xué)知識(shí)之文件操作的相關(guān)資料,需要的朋友可以參考下2021-05-05Python利用前序和中序遍歷結(jié)果重建二叉樹的方法
這篇文章主要介紹了Python利用前序和中序遍歷結(jié)果重建二叉樹的方法,實(shí)例分析了Python二叉樹的定義與遍歷操作技巧,需要的朋友可以參考下2016-04-04python部署chineseocr_lite的實(shí)現(xiàn)示例
本文主要介紹了python部署chineseocr_lite的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07python對(duì)列進(jìn)行平移變換的方法(shift)
今天小編就為大家分享一篇python對(duì)列進(jìn)行平移變換的方法(shift),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-01-01Python實(shí)現(xiàn)暴力破解有密碼的zip文件的方法
這篇文章主要介紹了Python實(shí)現(xiàn)暴力破解有密碼的zip文件的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03