如何为龙卷风IOStream设置超时?

时间:2013-08-07 03:22:11

标签: python sockets tornado

如何为龙卷风IOStream设置超时?

我尝试通过以下方式构建IOStream:

sock = socket.socket()
sock.settimeout(5)
self.stream = tornado.iostream.IOStream(sock)

但是当我打电话给stream.read_bytes()时,它仍然会一直等待。

1 个答案:

答案 0 :(得分:2)

您不能使用socket.settimeout(),因为它是为阻止IO而设计的,而Tornado提供了非阻塞IO。

Tornado高度面向Web和HTTP IO,它不允许在没有极度痛苦的情况下进行低级网络编程(IOStream的来源可怕)。

在套接字上设置超时的最佳方法是使用select.select()select.poll()等,但将此类方法与Tornado集成是一件痛苦的事。

我设法使用gen.with_timeout和脏黑客的组合执行超时读取以清除流的状态。

from tornado import gen
from tornado.ioloop import IOLoop
from tornado.tcpclient import TCPClient

timeout = 5
io_loop = IOLoop.current()
factory = TCPClient(io_loop=io_loop)

@gen.coroutine
def run():
    stream = yield factory.connect('127.0.0.1', 1234)
    try:
        future = stream.read_bytes(128)
        data = yield gen.with_timeout(
            timeout=io_loop.time() + timeout,
            future=future,
            io_loop=io_loop,
        )
    except gen.TimeoutError:
        # A dirty hack to cancel reading and to clear state of the stream, so
        # stream will be available for reading in future
        io_loop.remove_handler(stream.socket)
        state = (stream._state & ~io_loop.READ)
        stream._state = None
        stream._read_callback = None
        stream._read_future = None
        stream._add_io_state(state)
祝你好运!