python socketserver超时

时间:2013-03-29 15:09:14

标签: python sockets socketserver

我正在实现一个简单的服务器,如果3秒内没有收到任何内容,应该打印一条消息。

处理程序

class SingleTCPHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        while True:
            message = self.rfile.readline().strip()
            print message

服务器

class SimpleServer(SocketServer.TCPServer):
    timeout = 3

    def handle_timeout(self):
        print "Timeout"

    def __init__(self, server_address, RequestHandlerClass):
        SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)

这里我正在扩展TCPServer以测试超时方法。 我已将timeout属性设置为3。根据文档,如果该时间过去并且没有消息被发送到客户端handle_timeout()被调用,在我的情况下,只打印'超时'。

  

BaseServer.timeout

     

超时持续时间(以秒为单位),如果不需要超时则为无。    如果handle_request()在内部没有收到传入的请求    超时时间,调用handle_timeout()方法。

我启动服务器,观察它的输出。当我连接到它并发送一些消息时,通常会打印它们。但是,如果我不发送任何东西3秒或更长时间,则没有任何反应。好像timeouthandle_timeout()尚未实施。

这种行为可能是什么原因?

5 个答案:

答案 0 :(得分:3)

你不能为app loop调用server_forever()方法。 试试这个:

while True:
  self.handle_request()

handle_timeout()对我有用。

答案 1 :(得分:2)

您可以尝试在self.timeout声明超时(即将其设为实例字段而不是类变量吗?)

编辑(这是代码)

def handle_request(self):
           """Handle one request, possibly blocking.

          Respects self.timeout.
          """
          # Support people who used socket.settimeout() to escape
          # handle_request before self.timeout was available.
          timeout = self.socket.gettimeout()
          if timeout is None:
               timeout = self.timeout
           elif self.timeout is not None:
               timeout = min(timeout, self.timeout)
           fd_sets = select.select([self], [], [], timeout)
           if not fd_sets[0]:
               self.handle_timeout()
               return
           self._handle_request_noblock()

答案 2 :(得分:1)

最后,我删除了socketserver模块并直接使用socket模块,其中超时工作。

TIMEOUT = 3
HOST = '192.0.0.202'              
PORT = 2000             

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)

while 1:
    conn, addr = s.accept()
    conn.settimeout(TIMEOUT)
    while 1:
        try:
            data = conn.recv(1024)
            #Do things

        except socket.timeout:
            #Timeout occurred, do things

        if not data or P=='end':
            print 'Connection lost. Listening for a new controller.' 
            break

conn.close()

答案 3 :(得分:1)

以下是serve_forever()的文件:

  

处理请求直到显式shutdown()请求。轮询每个poll_interval秒关闭。 忽略self.timeout。如果您需要定期执行任务,请在另一个线程中执行

因此,serve_forever()只会检查shutdown()是否每poll_interval调用一次,其默认值为0.5秒。只有handle_request()关注timeout

以下是serve_forever()handle_request()的代码。

答案 4 :(得分:1)

首先,你是什么意思" [服务器]应该打印一条消息,如果3秒钟没有收到任何消息。"?

你的意思是服务器应该......

  1. 如果在某段时间内没有任何新请求,请关机?
  2. 如果在某段时间内没有完成连接,请关闭连接?
  3. 在第一种情况下,您可以使用BaseServer.timeout,但您还必须使用BaseServer.handle_request()代替BaseServer.server_forever()

    在第二种情况下,您应该设置SingleTCPHandler

    的超时
    class SingleTCPHandler(SocketServer.StreamRequestHandler):
        timeout = 3
        def handle(self):
            while True:
                message = self.rfile.readline().strip()
                print message
    

    对于想要使用自己的BaseRequestHandler实现的人:

    class MyRequestHandler(SocketServer.BaseRequestHandler):
        def handle(self):
            self.request.settimeout(3)