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
相关产品推荐
相关产品推荐

