Permalink
Switch branches/tags
Nothing to show
Find file
6a272b9 Aug 25, 2011
executable file 103 lines (87 sloc) 2.85 KB
#!/usr/bin/env python
import errno
import functools
import socket
from tornado import ioloop, iostream
NONBLOCKING = (errno.EAGAIN, errno.EWOULDBLOCK)
def conn_handler(sock):
buf = [""]
wait_write = [0]
def close():
io_loop.remove_handler(sock.fileno())
sock.close()
def handle(fd, events):
_buf = buf[0]
try:
_buf += sock.recv(1024)
if not _buf:
return close()
except socket.error as e:
if e.args[0] not in NONBLOCKING:
print e
return close()
try:
sent = sock.send(_buf)
buf[0] = _buf = _buf[sent:]
if _buf and not wait_write[0]:
io_loop.modify_handler(fd, io_loop.READ | io_loop.WRITE)
wait_write[0] = 1
elif wait_write[0]:
io_loop.modify_handler(fd, io_loop.READ | io_loop.WRITE)
wait_write[0] = 0
except socket.error as e:
if e.args[0] not in NONBLOCKING:
print e
return _close()
io_loop.add_handler(sock.fileno(), handle, io_loop.READ)
class Connection(object):
__slots__ = ('_conn', '_buf')
def __init__(self, connection):
self._conn = connection
self._buf = ""
io_loop.add_handler(connection.fileno(), self.handle, io_loop.READ)
def handle(self, fd, events):
try:
self._buf += self._conn.recv(1024)
if not self._buf:
return self._close()
except socket.error as e:
if e.args[0] not in NONBLOCKING:
print e
return self._close()
try:
sent = self._conn.send(self._buf)
self._buf = self._buf[sent:]
except socket.error as e:
if e.args[0] not in NONBLOCKING:
print e
return self._close()
def _close(self):
io_loop.remove_handler(self._conn.fileno())
self._conn.close()
self._conn = None
def connection_ready(sock, fd, events):
while True:
try:
connection, address = sock.accept()
except socket.error, e:
if e[0] not in (errno.EWOULDBLOCK, errno.EAGAIN):
raise
return
connection.setblocking(0)
#Connection(connection)
conn_handler(connection)
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setblocking(0)
sock.bind(("", 5000))
sock.listen(1024)
io_loop = ioloop.IOLoop.instance()
callback = functools.partial(connection_ready, sock)
io_loop.add_handler(sock.fileno(), callback, io_loop.READ)
try:
io_loop.start()
except KeyboardInterrupt:
io_loop.stop()
print "exited cleanly"