我读了很多东西,这仍然让我感到厌烦。我知道在使用原始套接字时如何做到这一点。以下工作正常,如果没有收到数据,则在1秒后超时:
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.TCPServer
与SocketServer.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循环运行一次,chunk不为空,然后再次执行self.request.recv()
,但客户端没有更多数据要发送,recv()无限期地阻塞......
我知道我可以实现一个小协议,检查终止字符串/字符,检查消息长度等,但我真的想在不可预见的情况下实现超时(例如客户端“消失”)。
我想设置并更新超时,即重置慢速客户端所需的chunk
之后的超时(尽管这是目前的次要问题)。< / p>
提前致谢
答案 0 :(得分:2)
您可以使用SocketServer.BaseRequestHandler.request.settimeout()
执行与使用原始套接字相同的操作。
例如:
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.request.settimeout(1)
...
在这种情况下,如果完成时间超过1秒,self.request.recv()
将终止。
答案 1 :(得分:0)
class MyTCPHandler(SocketServer.BaseRequestHandler):
timeout=5
...
...将引发异常(serve_forever()将捕获)并在调用recv()后5秒钟没有接收数据时关闭连接。但要小心;如果您发送数据的时间超过5秒,它也会关闭您的连接。
这可能是Python 3的具体内容,但它适用于我。