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

Python socket多客户端服务端报local variable 'connect'引用前未赋值错误

报错原因

  • 语法层面:else关键字后遗漏了冒号:,导致分支判断逻辑异常
  • 逻辑层面:当触发非服务端套接字的读事件时,你调用了仅在服务端新连接分支才会定义的connect变量,此时该变量未赋值就被引用,直接触发报错;同时没有存储对应客户端的地址信息,后续打印消息也无法匹配到对应客户端端口。

需调整的核心逻辑

  • 新增字典存储每个客户端套接字对应的端口信息
  • 非服务端读事件触发时,使用当前迭代到的套接字s接收数据,不要调用connect变量
  • 补上else后的冒号
  • 移除else分支内的server.close()逻辑,避免服务端被意外关闭
  • 客户端断开连接时,及时从监听列表和地址字典中移除对应套接字

修正后可运行代码

import socket
import select
import errno

host = '127.0.0.1'
PORT = 8080
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

socketForRead = [server]
# 新增字典存储每个套接字对应的客户端端口
client_addr = {}

server.bind((host, PORT))
server.listen(5)
print('wait for connection....')

def checkSocket(): 
    read_socket, write_socket, erros_socket = select.select(socketForRead, [], [])   
    for s in read_socket:
        if s is server:
            print('socket is ready')
            connect, adress = server.accept()                       
            print('new user connected ', str(adress[1]))
            connect.sendall(b'Server say hey!')
            connect.setblocking(0) 
            socketForRead.append(connect) 
            # 存储当前客户端套接字对应的端口
            client_addr[connect] = adress[1]
        # 补上漏掉的冒号
        else:
            try: 
                # 用当前迭代的套接字s接收数据,不要用connect
                data = s.recv(2048)
                if not data:
                    print(f'user {client_addr[s]} disconnect')
                    # 断开时移除监听和地址存储
                    socketForRead.remove(s)
                    del client_addr[s]
                    s.close()
                else:
                    # 从地址字典取当前客户端的端口
                    print('user', str(client_addr[s]), '>>>>', data.decode())
            except socket.error as e :
                if e.args[0] == errno.EWOULDBLOCK:
                    print('EWOULDBLOCK')
                    continue
                else:
                    print(e)
                    socketForRead.remove(s)
                    del client_addr[s]
                    s.close()
      
while 1:
    checkSocket()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:39:00