Наваял следующую конструкцию.
import select
import Queue
import socket
from threading import Thread
connections = {}
qq = Queue.Queue()
epoll = select.epoll()
class Connection(object):
def __init__(self, connection):
self.connection = connection
self.fileno = None
self.q = Queue.Queue()
class handlerThread(Thread):
def run(self):
while True:
idata, fileno = qq.get()
if idata:
odata = '\x00' # something
connections[fileno].q.put(odata)
if not connections[fileno].q.empty():
epoll.modify(fileno, select.EPOLLIN | select.EPOLLOUT)
def main():
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(('0.0.0.0', 31337))
serversocket.listen(5)
serversocket.setblocking(0)
serversocket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
epoll.register(serversocket.fileno(), select.EPOLLIN)
try:
while True:
events = epoll.poll(1)
for fileno, event in events:
if fileno == serversocket.fileno():
connection, address = serversocket.accept()
connection.setblocking(0)
connections[connection.fileno()] = Connection(connection)
connections[connection.fileno()].fileno = connection.fileno()
odata = '\x00' # something
connections[connection.fileno()].q.put(odata)
epoll.register(connection.fileno(), select.EPOLLIN | select.EPOLLOUT)
elif event & select.EPOLLIN:
idata = connections[fileno].connection.recv(8192)
if not idata:
epoll.modify(fileno, 0)
try:
connections[fileno].connection.shutdown(socket.SHUT_RDWR)
except:
pass
else:
qq.put((idata, fileno))
elif event & select.EPOLLOUT:
if not connections[fileno].q.empty():
qsize = connections[fileno].q.qsize()
while (qsize):
odata = connections[fileno].q.get()
connections[fileno].connection.send(odata)
qsize -= 1
if connections[fileno].q.empty():
epoll.modify(fileno, select.EPOLLIN)
elif event & select.EPOLLHUP:
epoll.unregister(fileno)
connections[fileno].connection.close()
del connections[fileno]
elif event & select.EPOLLERR:
print "Error connection: ", fileno
finally:
epoll.unregister(serversocket.fileno())
epoll.close()
serversocket.close()
if __name__ == '__main__':
handlerThread().start()
main()
Прошу оценить и дать советы(заключения).
P.S. это мой первый серьезный проект на питоне - прошу сильно не бить.