Here is my server
"""Server using epoll method"""
import os
import select
import socket
import time
from oodict import OODict
addr = ('localhost', 8989)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(8)
s.setblocking(0) # Non blocking socket server
epoll = select.epoll()
epoll.register(s.fileno(), select.EPOLLIN) # Level triggerred
cs = {}
data = ''
while True:
time.sleep(1)
events = epoll.poll(1) # Timeout 1 second
print 'Polling %d events' % len(events)
for fileno, event in events:
if fileno == s.fileno():
sk, addr = s.accept()
sk.setblocking(0)
print addr
cs[sk.fileno()] = sk
epoll.register(sk.fileno(), select.EPOLLIN)
elif event & select.EPOLLIN:
data = cs[fileno].recv(4)
print 'recv ', data
epoll.modify(fileno, select.EPOLLOUT)
elif event & select.EPOLLOUT:
print 'send ', data
cs[fileno].send(data)
data = ''
epoll.modify(fileno, select.EPOLLIN)
elif event & select.EPOLLERR:
print 'err'
epoll.unregister(fileno)
client side input
ideer@ideer:/home/chenz/source/ideerfs$ telnet localhost 8989
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
123456
123456
^]
telnet> q
Connection closed.
server side output
ideer@ideer:/chenz/source/ideerfs$ python epoll.py
Polling 0 events
Polling 0 events
Polling 1 events
('127.0.0.1', 53975)
Polling 0 events
Polling 1 events
recv 1234
Polling 1 events
send 1234
Polling 1 events
recv 56
Polling 1 events
send 56
Polling 0 events
Polling 0 events
Polling 0 events
Polling 1 events
recv
Polling 1 events
send
Polling 1 events
recv
Polling 1 events
send
Polling 1 events
recv
Polling 1 events
send
Polling 1 events
recv
^CTraceback (most recent call last):
File "epoll.py", line 23, in <module>
time.sleep(1)
KeyboardInterrupt
It's strange that after the client has closed the connection, epoll still can poll recv and send events! Why does EPOLLERR event never happen? it's the same if you use EPOLLHUP.
I notice that the EPOLLERR event only happens when you try to write a closed connection. Besides this, is there another way to tell that whether the connection has been closed or not?
Is it correct to treat the connection as closed if you get nothing in a EPOLLIN event?