Socketserver keeps connection open

Hi,

I am using “socketserver” for a basic tcp server.

server = socketserver.TCPServer((self.host, self.port), TCPHandlerFs)
server.timeout = 0.5
try:
                while not self.ubreak:
                    server.handle_request()
finally:
                server.server_close()
                self.quit ()

The TCPHandlerFs class:

class TCPHandlerFs(socketserver.StreamRequestHandler)
(...)

def handle_timeout(self):
    print ('Timeout - closing connection')

My problem:

Some clients are connecting through 4G connections which are not too stable. Often the client loses connection, but the socketserver keeps it alive for a long time (thinks the client is still there) so the client cannot re-connect. Only a restart of the script solves the issue.

My thought was to do “something” with handle_timeout … first setting the timeout to 0.5, but I am stuck how to close the connection in there.

Maybe somebody has any (or a better) suggestion?

Best regards,

Mart

You will need to set a TCP keep alive time that suits your needs.

It used to default to 2 hours I recall. You may want to set it to a lot shorter like 30 seconds.

Hi Barry,

Thank you very much, that sounds clear.

I am overseeing an option to set the keep alive time here:

Could you provide me a quick example how to set it after creating the server:

server = socketserver.TCPServer((self.host, self.port), TCPHandlerFs)

Thank you very much!

These examples should get you going.

You just need the socket. Can you get that in handle_request?

Hi Barry,

Thanks again!

Yes, I have tested a bit. Within handle_request there is a socket instance available in self.request:

<socket.socket fd=5, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 10800), raddr=('127.0.0.1', 34118)>

But… the socket server instance also has a socket instance:

#create server
server = socketserver.TCPServer((self.host, self.port), TCPHandlerFs)
#server has a socket property
server.socket
#socket
<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 10800)>

I see the socket in handle_request is connected to a client.

Where would be the place to set the time out? And in which way time out can be set?

I am new to socket/socket server and still learning/reading.

Best regards,

Mart

Once you have enabled SO_KEEPALIVE the systems uses its configured setting for the times. On Linux you can configure these via sysctl.
You can override the system defaults using setsockopt() as is done in the examples on that programcreek page.

man tcp has in details on what the settings do.

In the production code I work on we turn on SO_KEEPALIVE and use the system settings. We do this so that we can tune the system without the need to change the code or restart the daemons handling the TCP connections.