python: 玩玩EPOLL 玩一会epoll,果然好玩 ``` import select import socket import time def svc(): EOL1 = b'\n\n' EOL2 = b'\n\r\n' response = b'HTTP/1.0 200 OK\r\nDate: Mon, 1 Jan 1996 01:01:01 GMT\r\n' response += b'Content-Type: text/plain\r\nContent-Length: 13\r\n\r\n' response += b'Hello, world!' # 创建套接字对象并绑定监听端口 serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) serversocket.bind(('0.0.0.0', 8080)) serversocket.listen(1) serversocket.setblocking(0) # 创建epoll对象,并注册socket对象的 epoll可读事件 epoll = select.epoll() epoll.register(serversocket.fileno(), select.EPOLLIN|select.EPOLLET) try: connections = {} requests = {} responses = {} while True: time.sleep(0.1) # 主循环,epoll的系统调用,一旦有网络IO事件发生,poll调用返回。这是和select系统调用的关键区别 events = epoll.poll(1) # 通过事件通知获得监听的文件描述符,进而处理 for fileno, event in events: print("event {}".format(event)) # 注册监听的socket对象可读,获取连接,并注册连接的可读事件 if fileno == serversocket.fileno(): print("start accept fileno {}".format(fileno)) connection, address = serversocket.accept() connection.setblocking(0) epoll.register(connection.fileno(), select.EPOLLIN|select.EPOLLET) connections[connection.fileno()] = connection requests[connection.fileno()] = b'' responses[connection.fileno()] = response elif event & select.EPOLLIN: # 连接对象可读,处理客户端发生的信息,并注册连接对象可写 msg = connections[fileno].recv(1) print("fileno {}, rec: {}".format(fileno, msg)) requests[fileno] += msg if msg == b'': epoll.modify(fileno, 0) connections[fileno].shutdown(socket.SHUT_RDWR) if EOL1 in requests[fileno] or EOL2 in requests[fileno]: epoll.modify(fileno, select.EPOLLOUT) print('-' * 40 + '\n' + requests[fileno].decode()[:-2]) elif event & select.EPOLLOUT: print("select.EPOLLOUT start") # 连接对象可写事件发生,发送数据到客户端 byteswritten = connections[fileno].send(responses[fileno]) responses[fileno] = responses[fileno][byteswritten:] if len(responses[fileno]) == 0: epoll.modify(fileno, 0) connections[fileno].shutdown(socket.SHUT_RDWR) elif event & select.EPOLLHUP or event & (select.EPOLLIN | select.EPOLLRDHUP): print("select.EPOLLHUP start") epoll.unregister(fileno) connections[fileno].close() del connections[fileno] finally: epoll.unregister(serversocket.fileno()) epoll.close() serversocket.close() serversocket.close() def cli(): host = "localhost" port = 8164 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) try: while 1: msg = input() if msg == 'close': s.close() return s.send(msg.encode()) # print(s.recv(1024)) finally: s.close() # svc() # cli() import sys print(sys.argv) if sys.argv[1] == 'cli': cli() else: svc() ``` 来自 大脸猫 写于 2018-09-07 16:43 -- 更新于2020-10-19 13:06 -- 0 条评论