目录
引言
最近越来越依赖豆包、DS或者Kimi生成代码,这些工具的代码生成能力也有了显著提高,但是仍然会有些错误,解决这些错误其实还是需要经验的,代码生成对于新手其实不够友好。
代码问题
最近为了解决两块嵌入式开发板在不同的内网中无法直接通信的问题,决定在公网建立一个摆渡机,摆渡机上运行一个Python脚本来实现互相通信。豆包很快生成了测试代码:
import socket
import threading
# 定义服务器监听的地址和端口
SERVER_HOST = '0.0.0.0'
SERVER_PORT = 12345
# 用于存储两个客户端的连接
clients = []
# 处理客户端连接的函数
def handle_client(client_socket):
global clients
try:
while True:
# 接收客户端发送的数据
data = client_socket.recv(1024)
if not data:
break
# 找到另一个客户端并转发数据
for client in clients:
if client != client_socket:
client.sendall(data)
except Exception as e:
print(f"Error handling client: {e}")
finally:
# 客户端断开连接时,从列表中移除
if client_socket in clients:
clients.remove(client_socket)
client_socket.close()
# 创建服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定地址和端口
server_socket.bind((SERVER_HOST, SERVER_PORT))
# 开始监听
server_socket.listen(2)
print(f"Server listening on {SERVER_HOST}:{SERVER_PORT}")
try:
while len(clients) < 2:
# 等待客户端连接
client_socket, client_address = server_socket.accept()
print(f"Accepted connection from {client_address}")
clients.append(client_socket)
# 为每个客户端创建一个线程来处理数据
client_thread = threading.Thread(target=handle_client, args=(client_socket,))
client_thread.start()
except KeyboardInterrupt:
print("Server shutting down...")
finally:
# 关闭所有客户端连接和服务器套接字
for client in clients:
client.close()
server_socket.close()
这个代码看上去还不错,但是测试过程中发现两个客户端登录之后,只要客户端一发送数据,服务器就会出现错误:
Error handling client: [Errno 9] Bad file descriptor
把这个错误给豆包,豆包的回答是
当服务器端代码出现
Error handling client: [Errno 9] Bad file descriptor
错误时,这个错误通常表示在尝试使用一个无效的文件描述符(在网络编程里,套接字可以看作是一种特殊的文件描述符)进行操作,以下是可能的原因及解决办法:
无效的文件描述符这个判断是对的,但是它给的解决方案不靠谱,只是增加了出错处理,如果发现句柄非法就删除这个句柄,没有找到它生成的代码中的逻辑错误。
出错原因
仔细阅读代码,就会发现其实错误来自finally的处理,当有两个客户端连接后,就会执行下面这部分,而这部分就会导致客户端被关闭,从而无法转发数据了。
finally:
# 关闭所有客户端连接和服务器套接字
for client in clients:
client.close()
server_socket.close()
结语
目前看,大模型在逻辑分析方面仍然不足,当发现错误的时候不能找出这种隐蔽的问题,其实对程序员的调试经验要求还是挺高的。