仿照《how to use linux epoll with python》写的一个聊天室程序,比较简单。
python版本:2.7.3
#!/usr/bin/python
# -*- coding:utf-8 -*-
import socket, select
for res in socket.getaddrinfo('0.0.0.0', 1025, socket.AF_INET, socket.SOCK_STREAM):
fa, socktype, proto, canonname, sa = res
SockServer = socket.socket(fa, socktype, proto)
SockServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
SockServer.bind(sa)
SockServer.listen(5)
epoll = select.epoll()
epoll.register(SockServer.fileno(), select.EPOLLIN)
try:
conns={}; addrs={}
while True:
for fileno, event in epoll.poll(1):
if fileno == SockServer.fileno():
conn, addr = SockServer.accept()
epoll.register(conn.fileno(), select.EPOLLIN)
conns[conn.fileno()] = conn
addrs[conn.fileno()] = addr
conn.send("--- Welcome to server. Type EXIT to quit. ---\n")
print '[server]: accept connection from %s<%s>' % addr
elif event & select.EPOLLIN:
message = conns[fileno].recv(1024)
print "%s<%s> say: " % (addrs[fileno][0], addrs[fileno][1]) + message.strip()
if b'EXIT' in message:
epoll.modify(fileno, select.EPOLLOUT)
for key in conns.keys():
if key != fileno:
conns[key].send('%s<%s> say: %s' % (addrs[key][0], addrs[key][1], message))
elif event & select.EPOLLOUT:
epoll.modify(fileno, 0)
conns[fileno].shutdown(socket.SHUT_RDWR)
elif event & select.EPOLLHUP:
epoll.unregister(fileno)
conns[fileno].close()
print '[server]: %s<%s> quit.' % addrs[fileno]
del conns[fileno]
del addrs[fileno]
finally:
epoll.unregister(SockServer.fileno())
epoll.close()
SockServer.close()
程序运行如图: