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

Python Socket聊天室出现ConnectionRefusedError [WinError 10061]报错

Python多用户聊天室10061连接报错排查

问题相关代码

服务端代码

import threading
import socket

# 配置本地监听地址与端口
host = '127.0.0.1'
port = 9879

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen()

# 存储已接入客户端与对应昵称
clients = []
nicknames = []

# 广播消息给所有已连接客户端
def broadcast(message):
    for client in clients:
        client.send(message)

# 处理单客户端的消息收发
def handle (client):
    while True:
        try:
            message = client.recv(1024)
            broadcast(message)
        except:
            # 连接断开时移除客户端信息
            index = clients.index(client)
            clients.remove(client)
            client.close()
            nickname = nicknames[index]
            broadcast(f'{nickname} already left the chat!'.encode('ascii'))
            nicknames.remove(nickname)
            break

# 监听客户端接入
def receive():
    while True:
        client, address = server.accept()
        print(f"Conncected with {str(address)}")
        client.send('NICKNAME'.encode('ascii'))
        nickname = client.recv(1024).decode('ascii')
        nicknames.append(nickname)
        clients.append(client)
        
        print(f'The nickname of the client is {nickname}')
        broadcast(f'{nickname} joined the chat!'.encode('ascii'))
        client.send('Connected to the server!'.encode('ascii'))
        
        # 为每个客户端启动独立处理线程
        thread = threading.Thread(target = handle, args = (client,))
        thread.start()
print("Server is waiting for client...")

客户端代码

import socket
import threading 

# 输入昵称
nickname = input("Input your nickname: ")
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 9879))

# 接收服务端消息
def receive():
    while True:
        try:
            message = client.recv(1024).decode('ascii')
            if message == 'NICKNAME':
                client.send(nickname.encode('ascii'))
            else:
                print(message)
        except:
            print("An error occurred!")
            client.close()
            break

# 发送用户输入的消息
def write():
    while True:
        message = f'{nickname}: {input("")}'
        client.send(message.encode('ascii'))

# 启动收发线程
receive_thread = threading.Thread(target = receive)
receive_thread.start()

write_thread = threading.Thread(target = write)
write_thread.start()

触发报错

Traceback (most recent call last):
  File "C:\Users\march\Documents\Programming\Pyhton\client.py", line 8, in <module>
    client.connect(('127.0.0.1', 9879))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it

故障根因

触发10061连接拒绝的核心原因是服务端未实际启动监听循环。
查看服务端代码逻辑,定义完负责接入监听的receive()函数后,仅打印了等待客户端的提示文本,没有调用receive()函数。服务端代码运行到打印语句后就直接执行完毕、进程退出,9879端口没有任何进程处于监听状态,客户端发起连接时操作系统会直接返回拒绝响应。
之前判断9879端口可用,实际是服务端退出后端口处于空闲状态,没有程序在该端口响应连接请求,和端口被占用的场景完全不同。

修复方案

在服务端代码最后一行补充receive()函数调用,启动监听循环:

print("Server is waiting for client...")
receive()  # 新增该行

修复后严格按照先启动服务端进程,再启动客户端进程的顺序运行,即可正常连接进入聊天室。

可选优化项

  • 现有代码统一使用ascii编码传输内容,若需要支持中文聊天,将所有编码、解码位置的ascii替换为utf-8,否则传输中文会触发编码报错。
  • 服务端多线程同时操作clients、nicknames两个列表存在竞态风险,建议增加线程锁保护列表读写,避免多线程并发修改触发索引异常。
  • 客户端当前逻辑是先输入昵称再发起服务端连接,建议调整为连接成功、收到服务端的昵称请求指令后再提示用户输入昵称,避免服务端未启动时用户做无效输入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:48:23