Python控制ESP32时报错:OSError [WinError 10038]非套接字操作
解决OSError: [WinError 10038] 套接字操作错误
问题原因
你遇到的OSError: [WinError 10038] An operation was attempted on something that is not a socket错误,根源在于socket的使用逻辑:
- 全局创建了一个
sock对象,每次调用tr()函数发送指令后,直接调用sock.close()关闭了这个套接字。 - 当第二次检测到蓝色物体再次调用
tr('R')时,尝试用已经被关闭的socket对象执行connect()操作,此时该socket已不再是有效的资源,因此触发错误。
解决方案
提供两种可行的修改方案,根据你的使用场景选择:
方案1:每次发送指令创建新Socket(适合低频率指令场景)
修改tr函数,将socket的创建、连接、发送、关闭逻辑都放在函数内部,避免复用已关闭的socket:
def tr(s): # 每次调用时新建socket实例 sock = socket.socket() try: sock.connect((host, port)) sock.send(s.encode('utf-8')) finally: # 确保无论是否发送成功,都关闭socket sock.close()
方案2:保持长连接(适合高频率指令场景)
在程序启动时建立一次socket连接,后续直接复用该连接发送指令,仅在程序结束时关闭连接,减少连接开销:
import cv2 import numpy as np import imutils import socket host = "192.168.4.1" # ESP32局域网IP port = 80 # ESP32服务端口 # 初始化并建立socket长连接 sock = socket.socket() try: sock.connect((host, port)) except Exception as e: print(f"连接ESP32失败: {str(e)}") exit(1) def tr(s): if s in ['L', 'R']: sock.send(s.encode('utf-8')) cap = cv2.VideoCapture(0) try: while True: _, frame = cap.read() hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower_blue = np.array([90,60,0]) upper_blue = np.array([121,255,255]) mask4 = cv2.inRange(hsv, lower_blue, upper_blue) cnts4 = cv2.findContours(mask4, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts4 = imutils.grab_contours(cnts4) for c in cnts4: area4 = cv2.contourArea(c) if 5000 < area4 < 50000: cv2.drawContours(frame, [c], -1, (0,255,0), 3) tr('R') M = cv2.moments(c) cx = int(M["m10"] / M["m00"]) cy = int(M["m01"] / M["m00"]) cv2.circle(frame, (cx, cy), 7, (255,255,255), -1) cv2.putText(frame, "Blue", (cx-20, cy-20), cv2.FONT_HERSHEY_SIMPLEX, 2.5, (255,255,255), 1) cv2.imshow("result", frame) # 修正退出逻辑:waitKey返回ASCII码,需与ord('q')比较 if cv2.waitKey(5) & 0xff == ord('q'): break finally: # 程序结束时释放所有资源 cap.release() cv2.destroyAllWindows() sock.close()
额外注意点
原代码中cv2.waitKey(5) & 0xff == 'q'存在逻辑错误,waitKey()返回的是按键的ASCII码值,应该与ord('q')比较才能正确响应退出操作。
内容的提问来源于stack exchange,提问作者NSuleiman Alothman
相关产品推荐
相关产品推荐

