日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

web静态服务器

發(fā)布時(shí)間:2025/3/17 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 web静态服务器 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

非阻塞網(wǎng)絡(luò)IO

  • 非阻塞的特點(diǎn):當(dāng)沒有數(shù)據(jù)來的時(shí)候不阻塞當(dāng)前進(jìn)程等待,而是報(bào)出一個(gè)異常 (套接字.setblocking(False))

IO多路復(fù)用

  • 多路IO好處就在于單個(gè)process就可以同時(shí)處理多個(gè)網(wǎng)絡(luò)連接的IO
  • 特點(diǎn): 通過一種機(jī)制使一個(gè)進(jìn)程能同時(shí)等待多個(gè)文件描述符,而這些文件描述(套接字描述符)其中的任意一個(gè)進(jìn)入讀就緒狀態(tài),epoll()函數(shù)就可以返回
  • epoll 只能在Linux中使用
  • EPOLLIN(可讀)
  • EPOLLOUT(可寫)
  • EPOLLET(ET模式)

水平觸發(fā)和邊緣觸發(fā)

  • LT(level trigger):會(huì)在數(shù)據(jù)存在的情況下一直通知
  • ET(edge trigger): 只在數(shù)據(jù)到達(dá)的一刻通知一次

文件描述符

  • 文件描述符就是對(duì)進(jìn)程內(nèi)部所擁有文件資源的一種描述的符號(hào),是一個(gè)無符號(hào)整數(shù)(0,1,2...)
  • 啟動(dòng)一個(gè)程序默認(rèn)啟動(dòng) 標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯(cuò)誤 sock.fileno()

web服務(wù)器-多線程

import socket import threadingdef request_handler(client_socket):"""專門來處理客戶端請(qǐng)求的函數(shù)"""# 接收用戶請(qǐng)求recv_data = client_socket.recv(1024)if not recv_data:print("客戶端已斷開連接")client_socket.close()return# 解碼數(shù)據(jù)recv_str_data = recv_data.decode()# 切割請(qǐng)求數(shù)據(jù)-->列表,取第0個(gè)元素 GET /index2.html HTTP/1.1\r\nrequest_line = recv_str_data.split("\r\n")[0]# 再次切割 取列表第一個(gè)元素 就是用戶路徑 /index2.htmlpath_info = request_line.split(" ")[1]if path_info == "/":path_info = "/index.html"try:# # 嘗試打開用戶需要的文件, 不存在則拋出異常# f = open("./static" + path_info, "rb")# # 如果文件較大 容易產(chǎn)生隱患# # 讀出文件數(shù)據(jù)# ret = f.read()# f.close()# with 語句 自動(dòng)將對(duì)象的資源驚醒釋放--> 上下文管理# 支持的數(shù)據(jù)資源有文件 socket 互斥鎖等# static文件夾為你訪問的數(shù)據(jù)(自備),與本程序放在同一目錄下with open("./static" + path_info, "rb") as f:# 讀出文件數(shù)據(jù)ret = f.read()except Exception as e:response_line = "HTTP/1.1 404 NOt Found\r\n"response_header = "Server: PythonServer2.0\r\n"response_body = "ERROR"response_data = response_line + response_header + "\r\n" + response_bodyclient_socket.send(response_data.encode())else:# 響應(yīng)行 響應(yīng)頭 \r\n 響應(yīng)體# 響應(yīng)行response_line = "HTTP/1.1 200 OK\r\n"# 響應(yīng)頭response_header = "Server: PythonServer1.0\r\n"# 響應(yīng)體request_body = ret# 報(bào)文拼接data = (response_line + response_header + "\r\n").encode() + request_body# 發(fā)送client_socket.send(data)finally:# 關(guān)閉client_socket.close()if __name__ == '__main__':# 創(chuàng)建套接字server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 地址重用(1.設(shè)置 0.取消)server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# 綁定端口server_socket.bind(("", 8888))# 監(jiān)聽server_socket.listen(128)while True:# 取出一個(gè)客戶端套接字用以通信client_socket, client_address = server_socket.accept()print("接收到來自客戶端%s的請(qǐng)求" % str(client_address))# request_handler(client_socket)# 為每個(gè)客戶端請(qǐng)求的執(zhí)行都創(chuàng)建一個(gè)線程# 創(chuàng)建線程thd = threading.Thread(target=request_handler, args=(client_socket, ))thd.start() 復(fù)制代碼

web服務(wù)器-多進(jìn)程

import socket import multiprocessingdef request_handler(client_socket):"""專門來處理客戶端請(qǐng)求的函數(shù)"""# 接收用戶請(qǐng)求recv_data = client_socket.recv(1024)if not recv_data:print("客戶端已斷開連接")client_socket.close()return# 解碼數(shù)據(jù)recv_str_data = recv_data.decode()# 切割請(qǐng)求數(shù)據(jù)-->列表,取第0個(gè)元素 GET /index2.html HTTP/1.1\r\nrequest_line = recv_str_data.split("\r\n")[0]# 再次切割 取列表第一個(gè)元素 就是用戶路徑 /index2.htmlpath_info = request_line.split(" ")[1]if path_info == "/":path_info = "/index.html"try:# # 嘗試打開用戶需要的文件, 不存在則拋出異常# f = open("./static" + path_info, "rb")# # 如果文件較大 容易產(chǎn)生隱患# # 讀出文件數(shù)據(jù)# ret = f.read()# f.close()# with 語句 自動(dòng)將對(duì)象的資源驚醒釋放--> 上下文管理# 支持的數(shù)據(jù)資源有文件 socket 互斥鎖等 # static文件夾為你訪問的數(shù)據(jù)(自備),與本程序放在同一目錄下with open("./static" + path_info, "rb") as f:# 讀出文件數(shù)據(jù)ret = f.read()except Exception as e:response_line = "HTTP/1.1 404 NOt Found\r\n"response_header = "Server: PythonServer2.0\r\n"response_body = "ERROR"response_data = response_line + response_header + "\r\n" + response_bodyclient_socket.send(response_data.encode())else:# 響應(yīng)行 響應(yīng)頭 \r\n 響應(yīng)體# 響應(yīng)行response_line = "HTTP/1.1 200 OK\r\n"# 響應(yīng)頭response_header = "Server: PythonServer1.0\r\n"# 響應(yīng)體request_body = ret# 報(bào)文拼接data = (response_line + response_header + "\r\n").encode() + request_body# 發(fā)送client_socket.send(data)finally:# 關(guān)閉client_socket.close()if __name__ == '__main__':# 創(chuàng)建套接字server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 地址重用(1.設(shè)置 0.取消)server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# 綁定端口server_socket.bind(("", 8888))# 監(jiān)聽server_socket.listen(128)while True:# 取出一個(gè)客戶端套接字用以通信client_socket, client_address = server_socket.accept()print("接收到來自客戶端%s的請(qǐng)求" % str(client_address))# request_handler(client_socket)# 為每個(gè)客戶端請(qǐng)求的執(zhí)行都創(chuàng)建一個(gè)線程# 創(chuàng)建進(jìn)程pro = multiprocessing.Process(target=request_handler, args=(client_socket,))pro.start()# 關(guān)閉在父進(jìn)程的套接字,因?yàn)樵谧舆M(jìn)程中使用這個(gè)套接字,而父進(jìn)程中已經(jīng)不需要了# 父進(jìn)程和子進(jìn)程中共有兩個(gè)對(duì)象 引用底層的套接字資源 為了讓套接字正常使用client_socket.close() 復(fù)制代碼

web服務(wù)器-面向?qū)ο?/h3> import socket import multiprocessingclass HTTPServer(object):def __init__(self):"""創(chuàng)建服務(wù)器相關(guān)資源"""# 創(chuàng)建套接字server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 地址重用(1.設(shè)置 0.取消)server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# 綁定端口server_socket.bind(("", 8888))# 監(jiān)聽server_socket.listen(128)self.server_socket = server_socketdef request_handler(self, client_socket):"""專門來處理客戶端請(qǐng)求的函數(shù)"""# 接收用戶請(qǐng)求recv_data = client_socket.recv(1024)if not recv_data:print("客戶端已斷開連接")client_socket.close()return# 解碼數(shù)據(jù)recv_str_data = recv_data.decode()# 切割請(qǐng)求數(shù)據(jù)-->列表,取第0個(gè)元素 GET /index2.html HTTP/1.1\r\nrequest_line = recv_str_data.split("\r\n")[0]# 再次切割 取列表第一個(gè)元素 就是用戶路徑 /index2.htmlpath_info = request_line.split(" ")[1]if path_info == "/":path_info = "/index.html"try:# # 嘗試打開用戶需要的文件, 不存在則拋出異常# f = open("./static" + path_info, "rb")# # 如果文件較大 容易產(chǎn)生隱患# # 讀出文件數(shù)據(jù)# ret = f.read()# f.close()# with 語句 自動(dòng)將對(duì)象的資源驚醒釋放--> 上下文管理# 支持的數(shù)據(jù)資源有文件 socket 互斥鎖等# static文件夾為你訪問的數(shù)據(jù)(自備),與本程序放在同一目錄下with open("./static" + path_info, "rb") as f:# 讀出文件數(shù)據(jù)ret = f.read()except Exception as e:response_line = "HTTP/1.1 404 NOt Found\r\n"response_header = "Server: PythonServer2.0\r\n"response_body = "ERROR"response_data = response_line + response_header + "\r\n" + response_bodyclient_socket.send(response_data.encode())else:# 響應(yīng)行 響應(yīng)頭 \r\n 響應(yīng)體# 響應(yīng)行response_line = "HTTP/1.1 200 OK\r\n"# 響應(yīng)頭response_header = "Server: PythonServer1.0\r\n"# 響應(yīng)體request_body = ret# 報(bào)文拼接data = (response_line + response_header + "\r\n").encode() + request_body# 發(fā)送client_socket.send(data)finally:# 關(guān)閉client_socket.close()def start(self):while True:# 取出一個(gè)客戶端套接字用以通信client_socket, client_address = self.server_socket.accept()print("接收到來自客戶端%s的請(qǐng)求" % str(client_address))# request_handler(client_socket)# 為每個(gè)客戶端請(qǐng)求的執(zhí)行都創(chuàng)建一個(gè)線程# 創(chuàng)建進(jìn)程pro = multiprocessing.Process(target=self.request_handler, args=(client_socket,))pro.start()# 關(guān)閉在父進(jìn)程的套接字,因?yàn)樵谧舆M(jìn)程中使用這個(gè)套接字,而父進(jìn)程中已經(jīng)不需要了# 父進(jìn)程和子進(jìn)程中共有兩個(gè)對(duì)象 引用底層的套接字資源 為了讓套接字正常使用client_socket.close()if __name__ == '__main__':# 創(chuàng)建一個(gè)web服務(wù)器實(shí)例對(duì)象hs = HTTPServer()# 調(diào)用實(shí)例方法hs.start()復(fù)制代碼

web服務(wù)器-協(xié)程

from gevent import monkeymonkey.patch_all() import gevent import socketclass HTTPServer(object):def __init__(self):"""創(chuàng)建服務(wù)器相關(guān)資源"""# 創(chuàng)建套接字server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 地址重用(1.設(shè)置 0.取消)server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# 綁定端口server_socket.bind(("", 8888))# 監(jiān)聽server_socket.listen(128)self.server_socket = server_socketdef request_handler(self, client_socket):"""專門來處理客戶端請(qǐng)求的函數(shù)"""# 接收用戶請(qǐng)求recv_data = client_socket.recv(1024)if not recv_data:print("客戶端已斷開連接")client_socket.close()return # 解碼數(shù)據(jù)recv_str_data = recv_data.decode()# 切割請(qǐng)求數(shù)據(jù)-->列表,取第0個(gè)元素 GET /index2.html HTTP/1.1\r\nrequest_line = recv_str_data.split("\r\n")[0]# 再次切割 取列表第一個(gè)元素 就是用戶路徑 /index2.htmlpath_info = request_line.split(" ")[1]if path_info == "/":path_info = "/index.html"try:# # 嘗試打開用戶需要的文件, 不存在則拋出異常# f = open("./static" + path_info, "rb")# # 如果文件較大 容易產(chǎn)生隱患# # 讀出文件數(shù)據(jù)# ret = f.read()# f.close()# with 語句 自動(dòng)將對(duì)象的資源驚醒釋放--> 上下文管理# 支持的數(shù)據(jù)資源有文件 socket 互斥鎖等# static文件夾為你訪問的數(shù)據(jù)(自備),與本程序放在同一目錄下with open("./static" + path_info, "rb") as f:# 讀出文件數(shù)據(jù)ret = f.read()except Exception as e:response_line = "HTTP/1.1 404 NOt Found\r\n"response_header = "Server: PythonServer2.0\r\n"response_body = "ERROR"response_data = response_line + response_header + "\r\n" + response_bodyclient_socket.send(response_data.encode())else:# 響應(yīng)行 響應(yīng)頭 \r\n 響應(yīng)體# 響應(yīng)行response_line = "HTTP/1.1 200 OK\r\n"# 響應(yīng)頭response_header = "Server: PythonServer1.0\r\n"# 響應(yīng)體request_body = ret# 報(bào)文拼接data = (response_line + response_header + "\r\n").encode() + request_body# 發(fā)送client_socket.send(data)finally:# 關(guān)閉client_socket.close()def start(self):while True:# 取出一個(gè)客戶端套接字用以通信client_socket, client_address = self.server_socket.accept()print("接收到來自客戶端%s的請(qǐng)求" % str(client_address))# 創(chuàng)建并執(zhí)行協(xié)程gevent.spawn(self.request_handler, client_socket)if __name__ == '__main__':# 創(chuàng)建一個(gè)web服務(wù)器實(shí)例對(duì)象hs = HTTPServer()# 調(diào)用實(shí)例方法hs.start()復(fù)制代碼

web服務(wù)器-命令行參數(shù)控制端口

from gevent import monkey monkey.patch_all() import socket import gevent import sysclass HTTPServer(object):def __init__(self,port):"""創(chuàng)建服務(wù)器相關(guān)的資源 """# 創(chuàng)建服務(wù)器套接字server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 為了防止服務(wù)器不能立馬重新使用相應(yīng)的端口 設(shè)置套接字地址重用選項(xiàng) 1設(shè)置 0取消server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# 綁定server_socket.bind(('', port))# 監(jiān)聽server_socket.listen(128)self.server_socket = server_socketdef request_handler(self, client_socket):"""專門用來處理客戶端請(qǐng)求的函數(shù)"""# 接收用戶請(qǐng)求recv_data = client_socket.recv(4096)if not recv_data:print("客戶端已經(jīng)斷開連接")client_socket.close()return # 如果客戶端已經(jīng)斷開連接 則不需要再執(zhí)行后續(xù)代碼 直接結(jié)束函數(shù)即可# 解碼數(shù)據(jù)recv_str_data = recv_data.decode()# 切割請(qǐng)求數(shù)據(jù) ----> 列表data_list = recv_str_data.split('\r\n')# print(data_list)# 列表 中的第0個(gè)元素就是請(qǐng)求行 GET /index.html HTTP/1.1request_line = data_list[0]# print(request_line)# 請(qǐng)求行中的 切割出來的列表中的第一個(gè)元素就是用戶的請(qǐng)求路徑path_info = request_line.split(" ")[1]# /index.html /home/python/1.txt 直接使用系統(tǒng)的根目錄存放數(shù)據(jù)容易引起數(shù)據(jù)安全問題# 在用戶請(qǐng)求的路徑前 加上一個(gè)指定路徑 這樣當(dāng)用戶訪問的時(shí)候就會(huì)訪問指定目錄下的數(shù)據(jù) 防止服務(wù)器其他數(shù)據(jù)被竊取# ./static + /index.htmlprint(path_info)# 當(dāng)用戶只輸入域名(IP) + [端口] 用戶請(qǐng)求路徑是/if path_info == '/':path_info = '/index.html'try:# # 嘗試打開用戶需要的文件 如果文件不存在則拋出異常# file = open("./static" + path_info, "rb")# # 如果文件比較大 容易產(chǎn)生隱患## # 讀出文件數(shù)據(jù)# file_data = file.read()## file.close()# with語句 自動(dòng)將對(duì)象的資源進(jìn)行釋放 ----> 上下文管理器# 支持的數(shù)據(jù)資源 有文件 socket 互斥鎖等# static文件夾為你訪問的數(shù)據(jù)(自備),與本程序放在同一目錄下with open("./static" + path_info, "rb") as file:# 讀出文件數(shù)據(jù)file_data = file.read()except Exception as e:response_line = "HTTP/1.1 404 Not Found\r\n"response_header = "Server: PythonServer2.0\r\n"response_body = "ERROR"response_data = response_line + response_header + "\r\n" + response_bodyclient_socket.send(response_data.encode())else:# 響應(yīng)行 響應(yīng)頭 \r\n 響應(yīng)體# 響應(yīng)行response_line = "HTTP/1.1 200 OK\r\n"# 響應(yīng)頭response_header = "Server: PythonServer2.0\r\n"# 響應(yīng)體 就是瀏覽器收到的文件數(shù)據(jù)response_body = file_data# 按照HTTP響應(yīng)報(bào)文格式 進(jìn)行拼接response_data = (response_line + response_header + "\r\n").encode() + response_body# 發(fā)送響應(yīng)報(bào)文 send不一定能夠全部發(fā)送完成 sendall能夠保證全部發(fā)送完成# client_socket.send(response_data)client_socket.sendall(response_data)finally:# 斷開連接client_socket.close()def start(self):while True:# 取出一個(gè)客戶端套接字用以通信client_socket, client_addr = self.server_socket.accept()print("接受到來自%s的連接請(qǐng)求" % str(client_addr))# 為每個(gè)客戶端請(qǐng)求的執(zhí)行 都創(chuàng)建一個(gè)線程# request_handler(client_socket)# 創(chuàng)建并且執(zhí)行 協(xié)程gevent.spawn(self.request_handler, client_socket)def main():# python3 web.py 端口號(hào)# sys.argv是一個(gè)列表 每個(gè)元素都是一個(gè)字符串if len(sys.argv) != 2:print("參數(shù)錯(cuò)誤")return# print(sys.argv)port = sys.argv[1]if not port.isdigit():print("端口號(hào)應(yīng)該是數(shù)字")returnport_number = int(port)# 創(chuàng)建一個(gè)web服務(wù)器實(shí)例httpserver = HTTPServer(port_number)# 啟動(dòng)web服務(wù)器 的運(yùn)行httpserver.start()if __name__ == '__main__':main()復(fù)制代碼

總結(jié)

以上是生活随笔為你收集整理的web静态服务器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。