You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3如何同时运行多个互不阻塞的循环 适配socket服务端场景

修复后的完整代码

import socket
import threading
import time
import sys

class SimpleServer:
    def __init__(self, port):
        self.host = socket.getfqdn()
        self.port = port
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.settimeout(None)
        self.client_sockets = []
        # 打印任务控制变量
        self.running_going_task = False
        self.going_thread = None

    def going_task(self):
        # 独立的定时打印逻辑
        while self.running_going_task:
            print("Going ...")
            time.sleep(5)

    def initialise(self):
        try:
            self.sock.bind((self.host, self.port))
        except socket.error as e:
            print(f"端口绑定失败: {e}")
            return
        self.sock.listen(5)
        self.server_thread = threading.Thread(target=self.serve_forever)
        self.server_thread.setDaemon(True)
        self.server_thread.start()

    def serve_forever(self):
        # 外层循环支持多客户端连接,断开后可接入新客户端
        while True:
            try:
                request, client_address = self.sock.accept()
                with request:
                    while True:
                        data = request.recv(1024)
                        if not data:
                            break

                        data = data.decode("utf-8").strip()
                        if data == 'Go':
                            # 避免重复启动打印线程
                            if not self.running_going_task:
                                self.running_going_task = True
                                self.going_thread = threading.Thread(target=self.going_task)
                                self.going_thread.daemon = True
                                self.going_thread.start()
                        elif data == 'Stop':
                            # 停止打印任务
                            self.running_going_task = False
                            if self.going_thread and self.going_thread.is_alive():
                                self.going_thread.join()
                            print('Sitting ...')
            except socket.error:
                continue

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("使用方式: python server.py <端口号>")
        sys.exit(1)
    port = int(sys.argv[1])
    server = SimpleServer(port)
    server.initialise()
    # 阻塞主进程避免直接退出
    while True:
        time.sleep(1)

核心修改说明

  • 新增running_going_task标志位和going_thread线程对象,控制打印任务启停,避免重复启动多线程
  • 把定时打印逻辑抽离为独立方法,放在单独线程运行,完全不阻塞socket消息接收
  • 修复原代码serve_forever仅能接收一次客户端连接的问题,加外层循环支持客户端断开后重新接入
  • 修复主入口重复调用serve_forever的冲突,改用简单休眠循环保持主进程存活
  • 补充命令行参数接收逻辑,解决原代码args.socket_port未定义的报错问题
  • 全程未使用subprocess,符合要求

测试方式

  1. 启动服务:python server.py 9999(可替换为任意可用端口)
  2. 用telnet/netcat连接服务端后发指令:
    • 发送Go回车,服务端每5秒打印一次Going ...
    • 发送Stop回车,服务端立刻打印Sitting ...并终止定时打印
  3. 客户端断开后服务端会持续监听新连接,不会退出

内容的提问来源于stack exchange,提问作者wolfguru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:12:03