Python SimpleHTTPRequestHandler server leaves socket in TIME_WAIT state after exiting

I have a simple server that extends SimpleHTTPRequestHandler

If I start and stop it without any requests to the server, I can restart the backup file on the same port without any problems.

When you start netstat, it looks like this:

  sam@hersheezy : server $ sudo netstat -na --program |  grep 8001
 tcp 0 0 0.0.0.0:8001 0.0.0.0:* LISTEN 23392 / python

After the request is made, netstat looks like this (even after the request is completed):

  sam@hersheezy : server $ sudo netstat -na --program |  grep 8001
 tcp 0 0 0.0.0.0:8001 0.0.0.0:* LISTEN 23392 / python    
 tcp 0 0 127.0.0.1:8001 127.0.0.1:48659 TIME_WAIT -

Then I kill the server using Cc, and netstat looks like this (at this moment I can not restart the server because the port is already in use):

  sudo netstat -na --program |  grep 8001
 tcp 0 0 127.0.0.1:8001 127.0.0.1:48674 TIME_WAIT - 

I obviously do not close something correctly. My code that sends the response is as follows:

""" reply is an object that can be json encoded that is written with a response code 200 """ def send_provider_reply(self, replyobj): try: str_reply = json.dumps(replyobj) self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() #do we need to send a newline?? self.wfile.write(str_reply) except: traceback.print_exc() self.send_err(500, 'failed after provider creation') 
+4
source share
1 answer

The socket option SO_LINGER does not allow the socket to go to TIME_WAIT. But TIME_WAIT exists for some reason: it should protect you from lingering packets from old connections. Therefore, the default TIME_WAIT is twice as long as the network circuit. So, it is ok to find some old connections at TIME_WAIT.

To give some context: on the server side, with listening sockets, there is the SO_REUSEADDR option. This allows the listening socket to succeed in binding until the end of TIME_WAIT. For server processes that should always listen on the same port (think: a web server on port 80, 443), this is a must.

typical python code for a server might contain something like the following:

 ... listener = socket(AF_INET, SOCK_STREAM) listener.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) listener.bind((HOST, PORT)) listener.listen(32) ... 
+5
source

Source: https://habr.com/ru/post/1399857/


All Articles