Python Web服务器 (epoll版的服务器)
- 用 epl = select.epoll # 来创建epoll对象
- epl.register(xxx.fileno(),select.EPOLLIN) # 将监听套接字对应的fd注册到epoll 中 fd_event_list = epl.poll (返回的是一个列表)
# 默认会堵塞,直到os检测到有数据到来,通过事件通知方式告诉这个程序,此时次啊会解堵塞。这样就不会在没有数据的时候一直循环执行浪费资源- xx.fileno 代表套接字的fd 即套接字对应的文件描述符
- 设定套接字有数据进来时候通知
- fd_event_list = [(fd,event),(就是套接字的对应文件描述符,和这个描述符的事件)]
- 使用 xxx.fileno 可以得到套接字的文件描述符,到有文件描述符不能直接得到套接字,所以可以用到字典把两样东西结合起来
import socket import re import time import select def service_client(client_socket,recv_data): # recv/send接受发送数据额 recv_list =recv_data.splitlines() req = re.search(r"/[^ ]*",recv_list[0]).group() if req: if req == '/': req = '/index.html' print(req) try: with open('D:\python\jichuu\Web服务器\moban897'+req,'rb') as f: response_body = f.read() except : response_header ="HTTP/1.1 404 NOT FOUND\n\r\n" response_body = '<h1>nonono</h1>' response_body = response_body.encode('utf-8') else: response_header ="HTTP/1.1 200 OK\n" response_header += "Content-Length:%d\n\r\n" %(len(response_body)) response_header = response_header.encode('utf-8') response = response_header + response_body client_socket.send(response) client_socket.close() def main(): # socket创建一个套接字 tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) tcp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # 一定要绑定IP和端口,就跟110一样,是固定的让人随时能知道 tcp_server.bind(('192.168.124.32',7890)) # listen使套接字变成可以被动链接 tcp_server.listen(128) tcp_server.setblocking(False) # 将套接字变为非堵塞 epl = select.epoll() # 创建eoll对象 # 将监听套接字对应的fd注册到epoll 中 epl.register(tcp_server.fileno(),select.EPOLLIN) epl_dict = dict() # 循环为多个客户端服务 while True: # 默认会堵塞,直到os检测到有数据到来,通过事件通知方式告诉这个程序 # 此时次啊会解堵塞。这样就不会在没有数据的时候一直循环执行浪费资源 fd_event_list = epl.poll for fd,event in fd_event_list: if fd == tcp_server.fileno(): new_socket,client_add = tcp_server.accept() epl.register(new_socket.fileno(),select.EPOLLIN) epl_dict[new_socket.fileno()] = new_socket elif event == select.EPOLLIN: recv_data = epl_dict[fd].recv(1024).decode("utf-8") if recv_data: service_client(epl_dict[fd],recv_data) else: epl_dict[fd].close() epl.unregister(fd) del epl_dict[fd] tcp_server.close() if __name__ == '__main__': main()