I've read quite a few things and this still escapes me. I know how to do it when using raw sockets. The following works just fine, times out after 1 second if no data is received:
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'
But when trying something similar when using SocketServer.TCPServer
with SocketServer.BaseRequestHandler
(not with SocketServer.StreamRequestHandler
where I know how to set a timeout) it seems not as trivial. I didn't find a way to set a timeout for receiving the data. Consider this snippet (not complete code):
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()
Suppose the client sends only 10 bytes. The while loop runs once, chunk is not empty, so then executes self.request.recv()
again but the client has no more data to send and recv() blocks indefinitely ...
I know I can implement a small protocol, check for terminating strings/chars, check message length etc., but I really want to implement a timeout as well for unforeseen circumstances (client "disappears" for example).
I'd like to set and also update a timeout, i.e. reset the timeout after every chunk
, needed for slow clients (though that's a secondary issue at the moment).
Thanks in advance