python epoll

网上的东西不可靠啊。。。要么就泛泛而谈要么就是代码有问题。。。。。。

import socket
import select
import queue

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

server_address = ("127.0.0.1", 8888)

serversocket.bind(server_address);

serversocket.listen(10)

print('服务器启动,监听IP:', server_address)

serversocket.setblocking(False)

timeout = 10

epoll = select.epoll()

epoll.register(serversocket.fileno(),select.EPOLLIN)

message_queues = {}

fd_to_socket = {serversocket.fileno():serversocket,}

while True:
    print('等待活动链接\r\n')
    events = epoll.poll(timeout)
    if not events:
        print('epoll超时,重新轮训')
        continue
    print('', len(events) , '个新事件需要处理, fd_to_socket:', len(fd_to_socket))

    for fd, event in events:
        socket = fd_to_socket[fd]
        if socket == serversocket :
            connection, address = serversocket.accept()
            print('新链接' , address)
            connection.setblocking(False)
            epoll.register(connection.fileno(),select.EPOLLIN)
            fd_to_socket[connection.fileno()] = connection
            #print('fd1:%s fd2:%s' % (fd, connection.fileno()))
            message_queues[connection] = queue.Queue()
            print(fd_to_socket)
        elif event & select.EPOLLHUP:
            print('Client Close %s' % fd)
            epoll.unregister(fd)
            fd_to_socket[fd].close()
            del fd_to_socket[fd]
        elif event & select.EPOLLIN:
            data = socket.recv(1024)
            if data:
                print('收到数据: ', data, '客户端: ', socket.getpeername())
                message_queues[socket].put(data)
                epoll.modify(fd,select.EPOLLOUT)
            else:
                epoll.modify(fd,select.EPOLLHUP)
                print('Client Close %s' % fd)
                epoll.unregister(fd)
                fd_to_socket[fd].close()
                del fd_to_socket[fd]
        elif event & select.EPOLLOUT:
            try:
                msg = message_queues[socket].get_nowait()
                socket.send(msg)
            except queue.Empty:
                print(socket.getpeername, " queue empty")
                epoll.modify(fd, select.EPOLLIN)


epoll.unregister(serversocket.fileno())
epoll.close()
serversocket.close()

按照我的理解,epoll模型是以事件为触发的。一旦一个fd上有任何的事件发生,epoll就会解除阻塞,那么接下来就要依据其fd找出我们要的那个socket对象,接着需要依据EPOLL消息的类型制定响应的策略。

不过我还有一事不解,为什么在telnet之后的\r\n被识别为无效之后并没有正确的将event modify到EPOLLHUP的事件上,非常诡异,希望知道的大神指点迷津。

posted @ 2018-02-01 01:58  coder-sunyuw  阅读(187)  评论(0编辑  收藏  举报