Python:如何在SocketServer.TCPServer中设置接收数据的超时
我读过很多东西,但我仍然没有意识到这一点。我知道如何使用原始套接字。如果未收到数据,则以下操作正常,在1秒后超时:Python:如何在SocketServer.TCPServer中设置接收数据的超时,python,sockets,timeout,socketserver,Python,Sockets,Timeout,Socketserver,我读过很多东西,但我仍然没有意识到这一点。我知道如何使用原始套接字。如果未收到数据,则以下操作正常,在1秒后超时: sock=socket.socket(socket.AF\u INET,socket.sock\u流) sock.setsockopt(socket.SOL_socket,socket.SO_REUSEADDR,1) sock.bind((主机、端口)) 短袜,听(1) 而1: conn,addr=sock.accept() 数据=“” 连接设置超时(1) 尝试: 而1: chun
sock=socket.socket(socket.AF\u INET,socket.sock\u流)
sock.setsockopt(socket.SOL_socket,socket.SO_REUSEADDR,1)
sock.bind((主机、端口))
短袜,听(1)
而1:
conn,addr=sock.accept()
数据=“”
连接设置超时(1)
尝试:
而1:
chunk=conn.recv(1024)
数据+=块
如果不是块:
打破
打印“读取:%s%”数据
conn.send(data.upper())
除(socket.timeout、socket.error、Exception)外,为e:
打印(str(e))
最后:
康涅狄格州关闭
打印“完成”
但是,当尝试将SocketServer.TCPServer
与SocketServer.BaseRequestHandler
一起使用时(而不是与SocketServer.StreamRequestHandler
一起使用时,我知道如何设置超时),它看起来并不是那么简单。我没有找到设置接收数据超时的方法。考虑这个片段(不是完整的代码):
类MyTCPHandler(SocketServer.BaseRequestHandler):
def句柄(自身):
数据=“”
而1:
chunk=self.request.recv(1024)
数据+=块
如果不是块:
打破
如果名称=“\uuuuu main\uuuuuuuu”:
主机,端口=“0.0.0.0”,9987
SocketServer.TCPServer.allow_reuse_address=True
server=SocketServer.TCPServer((主机,端口),MyTCPHandler)
服务器。永远为您服务()
假设客户端只发送10个字节。while循环运行一次,chunk不是空的,因此再次执行self.request.recv()
,但是客户端没有更多的数据要发送,并且recv()无限期地阻塞
我知道我可以实现一个小协议,检查终止字符串/字符,检查消息长度等,但我真的想实现一个超时,以及不可预见的情况(例如客户端“消失”)
我想设置并更新一个超时,即在慢客户端需要的每个块
之后重置超时(尽管这是目前的次要问题)
提前谢谢
class MyTCPHandler(SocketServer.BaseRequestHandler):
timeout=5
...
。。。将引发异常(SERVICE_forever()将捕获该异常),并在调用recv()后5秒未收到数据时关闭连接。不过要小心;如果你发送数据的时间超过5秒,它也会关闭你的连接
记住,这可能是特定于Python 3的,但它对我很有用。您可以使用
SocketServer.BaseRequestHandler.request.settimeout()
执行与原始套接字相同的操作
例如:
在这种情况下,如果完成时间超过1秒,self.request.recv()
将终止。您对此进行了研究吗?那是用来处理(等待)请求的。调用serve_forever()时,将忽略.timeout属性(请参见链接到的同一页)。我的问题是关于接收数据的超时,即在客户端连接之后。
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.request.settimeout(1)
...