非阻塞網絡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()
returnrecv_str_data = recv_data.decode()request_line = recv_str_data.split(
"\r\n")[0]path_info = request_line.split(
" ")[1]
if path_info ==
"/":path_info =
"/index.html"try: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:response_line =
"HTTP/1.1 200 OK\r\n"response_header =
"Server: PythonServer1.0\r\n"request_body = retdata = (response_line + response_header +
"\r\n").encode() + request_bodyclient_socket.send(data)finally:client_socket.close()
if __name__ ==
'__main__':server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)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))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()
returnrecv_str_data = recv_data.decode()request_line = recv_str_data.split(
"\r\n")[0]path_info = request_line.split(
" ")[1]
if path_info ==
"/":path_info =
"/index.html"try: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:response_line =
"HTTP/1.1 200 OK\r\n"response_header =
"Server: PythonServer1.0\r\n"request_body = retdata = (response_line + response_header +
"\r\n").encode() + request_bodyclient_socket.send(data)finally:client_socket.close()
if __name__ ==
'__main__':server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)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))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)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()
returnrecv_str_data = recv_data.decode()request_line = recv_str_data.split(
"\r\n")[0]path_info = request_line.split(
" ")[1]
if path_info ==
"/":path_info =
"/index.html"try: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:response_line =
"HTTP/1.1 200 OK\r\n"response_header =
"Server: PythonServer1.0\r\n"request_body = retdata = (response_line + response_header +
"\r\n").encode() + request_bodyclient_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))pro = multiprocessing.Process(target=self.request_handler, args=(client_socket,))pro.start()client_socket.close()
if __name__ ==
'__main__':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)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()request_line = recv_str_data.split(
"\r\n")[0]path_info = request_line.split(
" ")[1]
if path_info ==
"/":path_info =
"/index.html"try: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:response_line =
"HTTP/1.1 200 OK\r\n"response_header =
"Server: PythonServer1.0\r\n"request_body = retdata = (response_line + response_header +
"\r\n").encode() + request_bodyclient_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__':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)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')request_line = data_list[0]path_info = request_line.split(
" ")[1]
print(path_info)
if path_info ==
'/':path_info =
'/index.html'try: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:response_line =
"HTTP/1.1 200 OK\r\n"response_header =
"Server: PythonServer2.0\r\n"response_body = file_dataresponse_data = (response_line + response_header +
"\r\n").encode() + response_bodyclient_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))gevent.spawn(self.request_handler, client_socket)def main():
if len(sys.argv) != 2:
print(
"參數錯誤")
returnport = sys.argv[1]
if not port.isdigit():
print(
"端口號應該是數字")
returnport_number = int(port)httpserver = HTTPServer(port_number)httpserver.start()
if __name__ ==
'__main__':main()
復制代碼
總結
以上是生活随笔為你收集整理的web静态服务器的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。