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ù)長(zhǎng)度是否為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ù)長(zhǎng)度是否為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)文章
關(guān)于tensorflow的幾種參數(shù)初始化方法小結(jié)
今天小編就為大家分享一篇關(guān)于tensorflow的幾種參數(shù)初始化方法小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-01-01
python實(shí)現(xiàn)登錄與注冊(cè)功能
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)登錄與注冊(cè)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
簡(jiǎn)單了解python的內(nèi)存管理機(jī)制
這篇文章主要介紹了簡(jiǎn)單了解python的內(nèi)存管理機(jī)制,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07
jupyter 實(shí)現(xiàn)notebook中顯示完整的行和列
這篇文章主要介紹了jupyter 實(shí)現(xiàn)notebook中顯示完整的行和列,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04

