如何正确关闭基于Python的TCP服务器?

时间:2018-05-25 09:49:49

标签: python multithreading python-3.x tcp

我有一个基于Python 3的套接字服务器,监听TCP连接。 它工作得很好,但现在我希望能够关闭整个应用程序"优雅",即使还有一个或多个客户端仍然连接到服务器。

以下代码只是演示了结构,我删除了一些对问题不重要的函数:

    def createContentHandler(server = None):
        """
        Creates TCP Request Handler with given message handler
        """
        class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
            def handle(self):
                """
                Request handler in a loop receives and handles message and send back response
                """
                id = threading.get_ident()
                sock = self.request
                try:
                    while True:
                        msg = self.receiveMessage()
                        data = msg.decode("utf-8")
                        response = server._msghandler.handle(data)
                        self.sendMessage(response)
                except ConnectionResetError as e:
                    sock.close()
                    print("socket close by client")
                except Exception as e:
                    sock.close()
                    print("socket close by other reason")




        return ThreadedTCPRequestHandler

    #======================== CLASS =====================================       

    class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
        """
        Handle each request in a separate thread.
        """

    #======================== CLASS =====================================       

    class Socket_Server():

        def __init__(self, *, adress, port, msghandler):
            super(Socket_Server, self).__init__()
            self._adress = adress
            self._port = port
            self._msghandler = msghandler


        def run(self):
            print('TCP socket server starting...')
            server_address = (self._adress, self._port)
            tcpHandler = createContentHandler(self) 
            print('TCP socket server is running.')
            with ThreadedTCPServer(server_address, tcpHandler) as server:
                self._server = server
                server.serve_forever(0.5)

        def shutdown(self):
            if self._server is not None:
                self._server.shutdown()
                self._server.server_close()
                print("Server is shut down")

原则上,服务器由server.serve_forever()启动,并且(由于背后的一些魔力),内容处理程序在每个连接的单独线程中启动。

内容处理程序调用{​​{1}},内部调用self.receiveMessage()以从套接字接收数据。这个电话是封锁的。

当我想关闭应用程序时,我从主线程调用服务器上的sock.recv(count)。我收到消息shutdown(),但应用程序仍然挂在执行阻止接收的位置。仅当所有客户端都已断开连接时,由于处理"Server is shut down"

,应用程序才会完全退出

如何强制连接的内容处理程序按需关闭?实际上我必须打破内容处理程序中循环内的阻塞调用,但是如何?

0 个答案:

没有答案