1

我正在实现一个简单的服务器,如果 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用于测试超时方法。我已将属性设置timeout3. 根据文档,如果该时间过去并且没有消息发送到客户端handle_timeout(),则调用它,在我的情况下,它只会打印“超时”。

BaseServer.timeout

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

我启动服务器,并观察它的输出。当我连接到它并发送一些消息时,它们通常会被打印出来。但是,如果我在 3 秒或更长时间内没有发送任何内容,则不会发生任何事情。好像timeoutandhandle_timeout()还没有实现。

这种行为的根源可能是什么?

4

5 回答 5

4

您不得为应用程序循环调用 server_forever() 方法。试试这个:

while True:
  self.handle_request()

然后,handle_timeout() 对我有用。

于 2013-10-14T23:38:05.663 回答
3

您可以尝试在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()
于 2013-03-29T15:18:35.500 回答
2

这是serve_forever()的文档:

处理请求,直到一个明确的 shutdown() 请求。每 poll_interval 秒轮询一次关机。忽略self.timeout。如果您需要执行周期性任务,请在另一个线程中执行

所以serve_forever()只会检查是否shutdown()被调用poll_interval,默认值为 0.5 秒。并且只handle_request()关心timeout.

这是serve_forever()handle_request()的代码。

于 2015-01-07T23:43:20.103 回答
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()
于 2013-05-08T07:48:36.673 回答
1

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

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

  1. 如果在特定时间段内没有任何新请求,则关闭?
  2. 如果在某个时间段内未完成连接,请关闭连接?

In the first case you can use BaseServer.timeout but you would also have to use BaseServer.handle_request() instead of BaseServer.server_forever().

In the second case you should have set the timeout for the SingleTCPHandler:

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

For people who want to use their own implementation of BaseRequestHandler:

class MyRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        self.request.settimeout(3)
于 2015-02-02T17:44:26.383 回答