Home > Mobile >  Restarting a python tcpserver based on sockerserver library
Restarting a python tcpserver based on sockerserver library

Time:07-15

Working with a tcp server - following snippet creates the server

import threading
import socketserver
import time

class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):

    #def __init__(self, a,b,c):
    #    super().__init__(request=a,client_address=b,server=c)

    def setup(self):
        pass

    def handle(self):
        pass

    def finish(self):
        pass

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

class Transport_Server:
    def __init__(self):

        # Port 0 means to select an arbitrary unused port
        HOST, PORT = "0.0.0.0", 5001

        self.server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
        #with self.server:
        ip, port = self.server.server_address

        self.server_thread = threading.Thread(target=self.server.serve_forever)

        # Exit the server thread when the main thread terminates
        self.server_thread.daemon = True
        self.server_thread.start()
        print("Server loop running in thread:", self.server_thread.name)


    def shutdown(self):
        self.server.shutdown()
        self.server_thread.join()

if __name__ == "__main__":


    transport = Transport_Server()

    print("Server started")
    time.sleep(5)
    
    print("Shutting down")
    transport.shutdown()

    print("Waiting")
    time.sleep(5)

    transport = Transport_Server()

    print("Server restarted")


Works fine.

But if I shutdown the server with object.server.shutdown() and then create a new instance of Transport_Server

I get

OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

CodePudding user response:

When a server is closed, the connection will not come to 'CLOSED' state immediately. instead, it will be in 'TIME_WAIT' state. to allow the client receive 'FIN_ACK' packet and to ttl down all delayed incoming packets.

During this 'TIME_WAIT' duration, we can't create new server in that address.

More details here: https://www.ietf.org/rfc/rfc793.txt


Checking the newly posted code above, server.shutdown() is just not enough, if you are restarting the server again immediately. as it just tells the serve_forever() to stop. but the ip address and port occupied stays in listening state.
when we add server.server_close() it cleans up the server and releasing the address, making it ready for a restart.

You can find the documentation here.

Below the updated Transport_Server.shutdown() function, which works fine.

def shutdown(self):
    self.server.shutdown()
    self.server_thread.join()
    self.server.server_close()
  • Related