防止Python SocketServer中请求被关闭

2 投票
1 回答
4086 浏览
提问于 2025-04-17 13:16

我正在使用 Python 的 socket 服务器,并且通过 Android 连接到这个服务器,定期发送消息。现在我遇到了一个问题,就是每次发送消息后,连接都会关闭,而我希望连接能够保持打开状态,直到 Android 自己决定关闭它。

目前的情况是这样的:

class SingleTCPHandler(SocketServer.StreamRequestHandler):
    def handle(self):
    try:
        while True:
            message = self.rfile.readline().strip()  # clip input at 1Kb            
            my_event = pygame.event.Event(USEREVENT, {'control':message})
            pygame.event.post(my_event)
    except KeyboardInterrupt:
        sys.exit(0)
    finally:
        self.request.close()

我通过在我的 handle() 函数里加一个 while True 来解决这个问题,但这个做法被批评为不好的解决方案,正确的做法应该是重写 process_requestshutdown 方法。

解决方案尝试

我把代码中的 while 去掉了,然后用 netcat 本地连接到服务器,发送了一条消息,想看看连接什么时候会关闭。

我想知道在什么方法之后连接会关闭,以便找出我需要重写的部分。

我用调试器逐步跟踪 serve_forever(),并跟到了这段代码:

> /usr/lib/python2.7/threading.py(495)start()
    494         try:
--> 495             _start_new_thread(self.__bootstrap, ())
    496         except Exception:

当执行到第 495 行时(我无法进入这行代码),连接就关闭了。

我有点怀疑,维护一个 socket 连接会这么麻烦吗?这正是我们选择通过 socket 通信的原因,希望能有一个持续的连接,而不是“每发送一条消息就建立一次连接”的系统。

有没有实现的想法,或者相关的链接?

1 个回答

9

每当有客户端连接时,handle 方法就会被调用,等这个方法执行完后,连接就会关闭。使用 while 循环是可以的。当客户端关闭连接时,就退出这个循环。

下面是一个例子(使用 Python 3 的语法):

class EchoHandler(socketserver.StreamRequestHandler):

    def setup(self):
        print('{}:{} connected'.format(*self.client_address))

    def handle(self):
        while True:
            data = self.request.recv(1024)
            if not data: break
            self.request.sendall(data)

    def finish(self):
        print('{}:{} disconnected'.format(*self.client_address))

撰写回答