2014-02-16 157 views
1

我读过不少东西,这仍然逃脱我。我知道如何在使用原始套接字时执行此操作。下面的作品就好了,超时1秒后,如果没有接收到数据:Python:如何设置在SocketServer.TCPServer接收数据的超时时间

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
sock.bind((HOST, PORT)) 
sock.listen(1) 
while 1: 
    conn, addr = sock.accept() 
    data = '' 
    conn.settimeout(1) 
    try: 
     while 1: 
      chunk = conn.recv(1024) 
      data += chunk 
      if not chunk: 
       break 
     print 'Read: %s' % data 
     conn.send(data.upper()) 
    except (socket.timeout, socket.error, Exception) as e: 
     print(str(e)) 
    finally: 
     conn.close() 
     print 'Done' 

但使用SocketServer.TCPServerSocketServer.BaseRequestHandler(不与SocketServer.StreamRequestHandler,我知道如何设置超时)时尝试类似的事情时,似乎不如同微不足道。我没有找到设置接收数据超时的方法。考虑这个片段(不完整的代码):

class MyTCPHandler(SocketServer.BaseRequestHandler): 
    def handle(self): 
     data = '' 
     while 1: 
      chunk = self.request.recv(1024) 
      data += chunk 
      if not chunk: 
       break 

if __name__ == "__main__": 
    HOST, PORT = "0.0.0.0", 9987 
    SocketServer.TCPServer.allow_reuse_address = True 
    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler) 
    server.serve_forever() 

假设客户端只发送10个字节。 while循环运行一次,一块是不是空的,所以后来再次执行self.request.recv()但客户没有更多的数据发送和recv()块无限期...

我知道我可以实现一个小协议,检查结束字符串/字符,检查消息长度等,但我真的想实现一个超时以及不可预见的情况(例如客户端“消失”)。

我想设置并且还更新超时,即重置每个chunk之后的超时(尽管这是当前的次要问题)。

在此先感谢

+0

你看过这个吗? http://docs.python.org/2/library/socketserver.html?highlight=tcpserver#SocketServer.BaseServer.timeout –

+1

这是为了处理(等待)请求。当调用serve_forever()时,忽略.timeout属性(请参阅链接到的同一页面)。我的问题是超时接收数据,即客户端连接后。 – Normadize

+0

明白了,对不起:) –

回答

0
class MyTCPHandler(SocketServer.BaseRequestHandler): 
timeout=5 
... 

...将引发一个异常(这serve_forever()将赶上)和关闭连接如果在5秒后没有调用接收后接收数据()。不过要小心,它也会关闭你的连接,如果你发送数据超过5秒。

这可能是Python 3特有的,但它适用于我。

1

您可以使用SocketServer.BaseRequestHandler.request.settimeout()做同样的事情,就像您使用原始套接字一样。

如:

class MyTCPHandler(SocketServer.BaseRequestHandler): 
    def handle(self): 
     self.request.settimeout(1) 
     ... 

在这种情况下self.request.recv()如果花费超过1秒的时间才能完成将终止。

相关问题