我正在实现一个简单的服务器,如果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秒或更长时间,则没有任何反应。好像timeout
和handle_timeout()
尚未实施。
这种行为可能是什么原因?
答案 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秒钟没有收到任何消息。"?
你的意思是服务器应该......
在第一种情况下,您可以使用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)