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

