2013-08-07 29 views

Trả lời

1

Bạn không thể sử dụng socket.settimeout(), vì thiết bị được thiết kế để chặn IO và Tornado cung cấp IO không chặn.

Tornado được định hướng rất cao trên Web và HTTP IO và nó không cho phép lập trình mạng ở mức độ thấp mà không bị đau cực độ (nguồn IOStream rất đáng sợ).

Cách tốt nhất để đặt thời gian chờ trên ổ cắm là sử dụng select.select(), select.poll(), v.v ... nhưng đó là một nỗi đau để tích hợp cách tiếp cận đó với Tornado.

Tôi đã quản lý để thực hiện các lần đọc với thời gian chờ sử dụng kết hợp của gen.with_timeout và một bản hack bẩn để xóa trạng thái của luồng.

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) 

Chúc may mắn!