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

添加Socket至clients数组后消息无法发送,请求技术支持

问题分析与解决方案

核心问题排查

你的代码存在两个关键问题,直接导致了"Hi!"消息无法发送:

  1. 缺少模块导入:代码里用到了socket和threading模块但未导入,运行时会直接抛出NameError,根本执行不到发送消息的逻辑。
  2. 多线程共享资源的线程安全问题:全局列表clients被多个线程同时操作,无锁情况下的append可能引发隐性的数据竞争,间接干扰socket的发送操作;另外原handle_client函数发送消息后直接结束,线程退出后socket可能被立即回收,客户端来不及接收。

修复后的完整代码

import socket
import threading

HOST = "127.0.0.1"
PORT = 123

clients = []
client_lock = threading.Lock()  # 新增线程锁,保证列表操作安全

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen()

def send_cmd(cmd):
    with client_lock:
        # 遍历列表副本,避免遍历过程中列表结构变化引发异常
        for client in clients.copy():
            try:
                client.send(cmd.encode())
            except Exception:
                # 移除已断开的客户端连接
                clients.remove(client)

def handle_client(client_socket):
    # 加锁后再将socket加入全局列表,避免线程竞争
    with client_lock:
        clients.append(client_socket)
    
    try:
        # 发送初始消息
        message = "Hi!"
        client_socket.send(message.encode())
        
        # 维持连接,监听客户端消息(否则线程会立即结束,socket被回收)
        while True:
            data = client_socket.recv(1024)
            if not data:
                break
            # 可在此处添加客户端消息处理逻辑
    except Exception as e:
        print(f"客户端连接异常: {e}")
    finally:
        # 清理资源:从列表移除并关闭socket
        with client_lock:
            if client_socket in clients:
                clients.remove(client_socket)
        client_socket.close()

def accept_connects():
    while True:
        client_socket, address = server_socket.accept()
        print(f"新客户端接入: {address}")
        # 设置守护线程,避免主线程退出后残留线程
        threading.Thread(target=handle_client, args=(client_socket,), daemon=True).start()

# 启动连接监听线程
threading.Thread(target=accept_connects, daemon=True).start()

# 保持主线程运行,否则程序会直接退出
input("按回车键关闭服务器...\n")

关键修复点说明

  • 模块导入:补上import socket和import threading,解决基础运行错误。
  • 线程锁:用threading.Lock()保护clients列表的所有操作(添加、遍历、删除),彻底避免多线程数据竞争。
  • 维持连接:在handle_client中添加循环监听客户端消息,防止线程发送消息后立即退出,保证socket存活直到客户端主动断开。
  • 资源清理:在finally块中统一处理socket关闭和列表移除,避免无效连接残留。

测试用客户端代码

用以下代码验证服务器是否正常发送"Hi!":

import socket

HOST = "127.0.0.1"
PORT = 123

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST, PORT))
print(client.recv(1024).decode())  # 应输出"Hi!"
client.close()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:05:11