pythonIO复用epoll

来源:互联网 发布:酷家乐是软件吗 编辑:程序博客网 时间:2024/06/08 09:39

epollserver.py代码

#coding:utf-8
import socket, select
import time


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 = select.epoll()
epoll.register(serversocket.fileno(), select.EPOLLIN)


try:
   connections = {}; requests = {}; responses = {}
   while True:
      events = epoll.poll(1)
      for fileno, event in events:
         if fileno == serversocket.fileno():
            connection, address = serversocket.accept()
            connection.setblocking(0)

    epoll.register(connection.fileno(), select.EPOLLIN)
            connections[connection.fileno()] = connection
            requests[connection.fileno()] = b''
            responses[connection.fileno()] = response
            print("conn add")
         elif event & select.EPOLLIN:
            requests[fileno] = connections[fileno].recv(1024)
            print("request",requests[fileno])
            #if EOL1 in requests[fileno] or EOL2 in requests[fileno]:
            def dealrequest():
                for i in range(5):
                    print("deal request",i)
                    time.sleep(1)
            dealrequest()
            epoll.modify(fileno, select.EPOLLOUT)
               #print('-'*40 + '\n' + requests[fileno].decode()[:-2])
         elif event & select.EPOLLOUT:
            print("client ready to recv data")
            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:
            epoll.unregister(fileno)

            connections[fileno].close()
            del connections[fileno]
finally:
   epoll.unregister(serversocket.fileno())
   epoll.close()
   serversocket.close()


epollclient.py代码

#coding:utf-8
import socket
import time


conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
conn.connect(("127.0.0.1",8080))


print("socket conn")
inputss = raw_input("send data or not:")
while True:
    inputs = raw_input("send data:")
    conn.send(inputs)
    inputs = raw_input("choose send or recv exit:")
    if inputs == "recv":
data = conn.recv(1024)
print("recv data:",data)
    elif inputs != "exit":
conn.send("send ---")
    else:
print("socket exit")
break
conn.close()

大概执行思路是

1.启动server端的时候,注epoll事件,然后开始epoll的监听事件

2.此时client连接时,会触发epoll的连接时间,此时判断出是一个连接事件后,对新建的连接进行编号,并且注册该新建连接的读时间,只有该连接在客户端发送数据就触发

epoll的读事件,此时读取到请求数据后,然后就调用相关函数进行处理,待数据处理完成后,此时对该连接进行可读事件注册,此时客户端读取数据就会触发epoll的写事件,就将处理后的数据进行返回,此时返回完成后注销该事件并断开该连接

3.如此循环就可以异步处理请求

ps:在while循环中,每次循环的触发事件必须要处理完毕后,才能处理下一个事件,假如在一个链接正在执行读的触发操作的时候,如果另一连接触发了事件,该事件会在本次连接处理完成之后再下一个循环处理另一个链接的触发事件

0 0
原创粉丝点击