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

Python异步处理Socket阻塞:实现等待连接时运行等待动画

解决Socket阻塞期间显示等待动画的问题

环境

  • Windows 11
  • Python 3.11.3

现有代码

等待动画函数

def waiting():
    while True:
        for i in range(3):
            print("Waiting")
            time.sleep(1)
            os.system('cls')
            print("Waiting.")
            time.sleep(1)
            os.system('cls')
            print("Waiting..")
            time.sleep(1)
            os.system('cls')
            print("Waiting...")
            time.sleep(1)
            os.system('cls')

Socket连接函数

def succesful_connect():
    host = socket.gethostname()
    port = 5000  
    your_host = socket.gethostname()
    your_host=socket.gethostbyname(your_host)
    print('Your IP:', your_host)
    server_socket = socket.socket()  
    server_socket.bind((host, port))  
    server_socket.listen(2)
    conn, address = server_socket.accept()  
    return conn, address

问题

代码中conn, address = server_socket.accept()会完全阻塞程序,直到有连接建立,这段时间内无法执行任何其他操作。之前尝试编写等待循环,但无法在连接成功后停止循环,希望通过异步方式让waiting()循环显示等待动画,直到连接成功建立。

解决方案

使用Python的threading模块将Socket连接逻辑放到子线程执行,主线程负责运行等待动画。通过全局标志和队列同步连接状态与传递连接对象,实现动画与连接的并行执行。

修改后的完整代码

import time
import os
import socket
import threading
from queue import Queue

# 用于传递连接结果的队列
result_queue = Queue()
# 标记是否已成功建立连接
connected = False

def waiting():
    while not connected:
        # 循环显示等待动画,用\r覆盖当前行减少闪屏
        for suffix in ["", ".", "..", "..."]:
            if connected:
                break
            print(f"Waiting{suffix}", end="\r")
            time.sleep(0.5)
    os.system('cls')

def successful_connect():
    global connected
    host = socket.gethostname()
    port = 5000  
    your_host = socket.gethostbyname(socket.gethostname())
    print('Your IP:', your_host)
    server_socket = socket.socket()  
    server_socket.bind((host, port))  
    server_socket.listen(2)
    # 等待客户端连接
    conn, address = server_socket.accept()  
    # 连接成功后更新状态
    connected = True
    print(f"\n已成功连接到客户端:{address}")
    # 将连接对象存入队列
    result_queue.put((conn, address))

if __name__ == "__main__":
    # 启动Socket连接子线程
    connect_thread = threading.Thread(target=successful_connect)
    connect_thread.start()
    
    # 主线程运行等待动画
    waiting()
    
    # 从队列获取连接结果
    conn, address = result_queue.get()
    
    # 后续可在此处处理连接(示例:接收客户端消息)
    data = conn.recv(1024).decode()
    if data:
        print(f"收到客户端消息:{data}")
    # 关闭连接
    conn.close()

代码说明

  1. 线程分离:将Socket连接逻辑放入子线程,避免accept()的阻塞特性影响主线程的动画显示。
  2. 状态同步:通过全局变量connected标记连接状态,主线程的等待动画循环会实时检查该变量,一旦连接成功就停止动画。
  3. 流畅输出:使用end="\r"覆盖当前行输出,替代频繁调用os.system('cls'),减少屏幕闪烁。
  4. 结果传递:利用Queue安全传递连接后的conn和address对象,避免全局变量的线程安全问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:08:18