利用epoll单任务高并发处理的HTTP服务器的实现
今天写了一个 利用 pythonselect
模块中的 epoll
实现单任务高并发的HTTP服务器,简单分享一下:
这里需要注意的是,在 windows中没有 epoll 方法,这个方法只存在 Linux 中
下面是具体代码:
在这里插入代码片import socket
import select
import re
def server_c(receve_msg):
recv_content1 = receve_msg.splitlines()
recv_content2 = re.match(r"[^/]+(/[^ ]*)", recv_content1[0])
try:
f = open("." + recv_content2.group(1), "rb")
response_content = f.read()
response_head = "HTTP/1.1 200 OK\r\n"
response_head += "Content-Legth:%d\r\n" % len(response_content)
response_head += "\r\n"
new_socket.send(response_head.encode("utf-8"))
new_socket.send(response_content)
except:
response_head = "HTTP/1.1 404 Error\r\n"
response_head += "\r\n"
new_socket.send(response_head)
response_content = "------------发生 404 错误-----------"
new_socket.send(response_content)
def main():
# 创建一个套接字
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定ip port
tcp_socket.bind(("", 7890))
# 设置侦听套接字
tcp_socket.listen(128)
tcp_socket.setblocking(False)
# 创建一个独立的空间
epl = select.epoll()
# 把 tcp_socket 加入这个 空间中
epl.register(tcp_socket.fileno(), select.EPOLLIN)
# 创建一个 空集合,用于存放新接收的 文件描述符和套接字
fd_newsock_dict = dict()
while True:
# 把 刚刚创建的 空间设置成 监听模式,用于等待消息的到来消息
# 这个地方默认为 堵塞,其接受的内容是一个 列表[(fd, event)]
fd_event_list = epl.poll()
# 进行循环解包,进一步判断
for fd, event in fd_event_list:
# 循环第一次,如果 文件描述符 是tcp_socket的,就进行侦听分离new_socket
if fd == tcp_socket.fileno():
# 等待客户端到来
new_socket, user_addr = tcp_socket.accept()
# 把 new_socket 加入创建的空间中
epl.register(new_socket.fileno(), select.EPOLLIN)
# 这里,需要标记 new_socket
fd_newsock_dict[new_socket.fileno()] = new_socket
elif event == select.EPOLLIN:
receve_msg = fd_newsock_dict[fd].recv(1024).decode("utf-8")
if receve_msg:
server_c(receve_msg)
else:
print("-------------客户端已经关闭的-----------")
fd_newsock_dict[fd].close()
epl.unregister(fd)
del fd_newsock_dict[fd]
if __name__ == '__main__':
main()