Python Socket多用户连接报错ConnectionRefusedError: [Errno 61]连接被拒绝
多用户Socket聊天程序连接失败问题
我用Socket实现支持多用户连接的聊天程序,本地测试时遇到问题:
- 启动绑定IP为127.0.0.1、端口为5555的服务器脚本;
- 第一个客户端脚本可成功连接服务器,但再次运行相同脚本模拟第二个用户连接时,抛出错误:
ConnectionRefusedError: [Errno 61] Connection refused
客户端代码:
ip = "127.0.0.1" port = 5555 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect((ip,port))
服务器代码:
import threading import socket host = "127.0.0.1" port = 5555 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((host, port)) server.listen() clients = [] def broadcast(message): for client in clients: client.send(message) def handle(client): while True: try: message = client.recv(1024) broadcast(message) except: break def recieve(): while True: client, address = server.accept() print(f"Connected with {str(address)}") client.send('NICK'.encode('ascii')) nickname = client.recv(1024).decode('ascii') clients.append(client) print(clients) print(f'Nickname of the client is {nickname}') broadcast(f'{nickname} joined the Chat'.encode('ascii')) client.send('Connected to the Server!'.encode('ascii')) # Handling Multiple Clients Simultaneously thread = threading.Thread(target=handle, args=(client,)) thread.start() print('Server is Listening ...') recieve()
问题根源与修复方案
核心问题
服务器卡在第一个客户端的昵称接收步骤,无法处理新的连接请求:
服务器在客户端连接后会发送NICK指令要求客户端回复昵称,但你的客户端代码没有处理这个请求,导致服务器一直阻塞在nickname = client.recv(1024).decode('ascii')这一行,无法回到server.accept()监听新连接,所以第二个客户端连接时被直接拒绝。
修复步骤
1. 修改客户端代码,添加昵称响应逻辑
客户端需要接收服务器的NICK请求并发送昵称,让服务器完成连接流程:
import socket ip = "127.0.0.1" port = 5555 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect((ip, port)) # 处理服务器的昵称请求 client.recv(1024) # 接收"NICK"指令 nickname = input("输入你的昵称: ") client.send(nickname.encode('ascii')) # 持续接收服务器消息 while True: msg = client.recv(1024).decode('ascii') print(msg)
2. 优化服务器异常处理(可选但推荐)
当前handle函数的异常处理过于宽泛,且未移除失效客户端,可能导致后续广播出错。修改为:
# 新增字典存储客户端与昵称的映射 clients = [] nicknames = {} def handle(client): while True: try: message = client.recv(1024) if message: broadcast(message) except: # 移除失效客户端并广播离开消息 index = clients.index(client) clients.remove(client) nickname = nicknames[client] del nicknames[client] client.close() broadcast(f"{nickname} 离开了聊天室".encode('ascii')) break # 在recieve函数中添加昵称映射存储 def recieve(): while True: client, address = server.accept() print(f"已连接 {str(address)}") client.send('NICK'.encode('ascii')) nickname = client.recv(1024).decode('ascii') clients.append(client) nicknames[client] = nickname # 存储昵称映射 print(f"客户端昵称: {nickname}") broadcast(f'{nickname} 加入了聊天室'.encode('ascii')) client.send('已连接到服务器!'.encode('ascii')) thread = threading.Thread(target=handle, args=(client,)) thread.start()
验证
修改后重启服务器,先运行第一个客户端输入昵称,服务器完成流程后会继续监听新连接;再运行第二个客户端,即可正常连接并加入聊天。
内容的提问来源于stack exchange,提问作者Beni
相关产品推荐
相关产品推荐

