これが私のサーバーです
"""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)
クライアント側の入力
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.
サーバー側出力
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
クライアントが接続を閉じた後でも、epoll が recv をポーリングしてイベントを送信できるのは奇妙です! EPOLLERR イベントが発生しないのはなぜですか? EPOLLHUP を使用する場合も同様です。
EPOLLERR イベントは、閉じた接続を書き込もうとしたときにのみ発生することに気付きました。これ以外に、接続が閉じられたかどうかを確認する別の方法はありますか?
EPOLLIN イベントで何も得られない場合、接続を閉じたものとして扱うのは正しいですか?