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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

web静态服务器

發布時間:2025/3/17 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 web静态服务器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

非阻塞網絡IO

  • 非阻塞的特點:當沒有數據來的時候不阻塞當前進程等待,而是報出一個異常 (套接字.setblocking(False))

IO多路復用

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

水平觸發和邊緣觸發

  • LT(level trigger):會在數據存在的情況下一直通知
  • ET(edge trigger): 只在數據到達的一刻通知一次

文件描述符

  • 文件描述符就是對進程內部所擁有文件資源的一種描述的符號,是一個無符號整數(0,1,2...)
  • 啟動一個程序默認啟動 標準輸入、標準輸出、標準錯誤 sock.fileno()

web服務器-多線程

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

web服務器-多進程

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

web服務器-面向對象

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

web服務器-協程

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

web服務器-命令行參數控制端口

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。