print("web服务器---epoll") import socket import re import select def service_client(new_socket,request): request_lines = request.splitlines() print("") print(">"*20) print(request_lines) file_name = "" ret= re.match(r"[^/]+(/[^ ]*)",request_lines[0]) if ret: file_name = ret.group(1) if file_name == "/": file_name = "/index.html" #返回HTTP格式的数据,给浏览器 try: f = open("./html" + file_name,"rb") except: response = "HTTP/1.1 404 NOT FOUND\r\n" response += "\r\n" new_socket.send(response.encode("utf-8")) else: html_content = f.read() f.close() response_body = html_content response_header = "HTTP/1.1 200 OK\r\n" response_body += "Content-Length:%d\r\n" % len(response_body) response_header = "\r\n" response = response_header.encode("utf-8") + response_body new_socket.send(response) #关闭套接字 #new_socket.close() def main(): """用来创建套接字""" # 1、创建套接字 tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #2、绑定 tcp_server_socket.bind(("",7890)) #3、变为监听套接字 tcp_server_socket.listen(128) tcp_server_socket.setblocking(False) # 将套接子变为非堵塞 #创建epoll对象 epl = select.epoll() #将监听套接字对应的文件描述符fd注册到epoll中 epl.register(tcp_server_socket.fileno(),select.EPOLLIN) fd_event_dict = dict() while True: fd_event_list = epl.poll() # 默认会堵塞,直到os监测到数据到来,通过事件通知方式 告诉这个程序,此时才会 # (fd,event),(套接字对应的文件描述符,这个文件描述符到底是什么事件,例如:可以调用revc接收等) for fd,event in fd_event_list: # 4、d等待新客户端的链接 if fd == tcp_server_socket.fileno(): new_socket,client_addr = tcp_server_socket.accept() epl.register(new_socket.fileno(),select.EPOLLIN) fd_event_dict[new_socket.fileno()] = new_socket elif event == select.EPOLLIN: # 判断已经链接的客户端是否又数据发送过来 recv_data = fd_event_dict[fd].recv(1024).decode("utf-8") if recv_data: service_client(fd_event_dict[fd],recv_data) else: fd_event_dict[fd].close() epl.unregister(fd) del fd_event_dict[fd] #关闭监听套接字 tcp_server_socket.close() if __name__ == "__main__": main()
python中用epolls实现服务器功能
最新推荐文章于 2021-01-26 20:33:04 发布