OSError: [Errno 48] Address already in use despite using allow_reuse_address

Viewed 26

I'm trying to create two separate HTTP Servers from a single python script. I have a setup as follows:

app.py:

app = Flask(__name__)

can_routes = {
    "/": 0
}
can_server = RemoteServer(host="127.0.0.1", port=9000, routes=can_routes, bustype="virtual", bitrate=50000)

if __name__ == "__main__":
    app.run("127.0.0.1", 8000, debug=True, threaded=True)
    can_server.serve_forever()

Where RemoteServer is implemented as follows, can_server.py:

class RemoteServer(ThreadingHTTPServer):
    """Server for CAN communication."""
    allow_reuse_address = True
    daemon_threads = True

    def __init__(self, host: str = "0.0.0.0", port: int = DEFAULT_PORT, routes: dict = None, ssl_context=None,
                 **config):
        """
        :param str host:
            Address to listen to.
        :param int port:
            Network port to listen to.
        :param ssl.SSLContext ssl_context:
            An SSL context to use for creating a secure WSS server.
        :param dict routes:
            {"/path": <channel>} mapping for routing to different channels
        :param str bustype:
            CAN interface to use.
        :param int bitrate:
            Forced bitrate in bits/s.
        """
        address = (host, port)
        self.config = config
        self.routes = routes

        #: List of :class:`can.interfaces.remote.server.ClientRequestHandler`
        #: instances
        self.clients = []
        HTTPServer.__init__(self, address, ClientRequestHandler)
        logger.info("Server listening on %s:%d", address[0], address[1])

        if ssl_context:
            self.socket = ssl_context.wrap_socket(self.socket, server_side=True)
            scheme_suffix = "s"
        else:
            scheme_suffix = ""

        logger.info("Connect using channel 'ws%s://localhost:%d/'",
                    scheme_suffix, self.server_port)
        logger.info("Open browser to 'http%s://localhost:%d/'",
                    scheme_suffix, self.server_port)


    def server_bind(self):
        if self.allow_reuse_address:
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.socket.bind(self.server_address)
        host, port = self.server_address[:2]
        self.server_name = socket.getfqdn(host)
        self.server_port = port

The problem is, every time i run this I get OSError: [Errno 48] Address already in use - even when I explicitly set self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - this doesn't seem to matter. I have validated that the server in fact receives a correct, and different address definition, which is unused. Both servers run separately in different terminal tabs work without issues. Am I missing something?

1 Answers

You can't have 2 active sockets bound to the same IP/Port at the same time, despite SO_REUSEADDR. What SO_REUSEADDRallows you to do is reopen an IP/Port that was previously closed and still in the TIME_WAIT state when a new socket wants to reopen it. That is not the case in your situation.

Related