如何通过Socket实现C#客户端向Python服务端发送图片
错误根因
- 核心问题:Python端接收到Socket返回的二进制PNG数据后,错误调用
str()将字节转为字符串存储,直接篡改了原始二进制结构,导致CV2解码时拿到无效数据抛出断言失败错误。 - 次要问题:接收数据的初始化容器为字符串
data = '',应该使用字节容器data = b''存储二进制数据。 - 潜在边界问题:接收报文头时未校验
recv(6)是否真的拿到了6个字节,网络波动时可能出现header截断,后续转长度直接出错。
修复后的服务端代码
import numpy as np import cv2 # 封装可靠的定长数据接收函数,解决单次recv数据截断问题 def recv_all(conn, length): data = b'' while len(data) < length: chunk = conn.recv(length - len(data)) if not chunk: # 连接异常断开返回空 return None data += chunk return data # 接收6位定长报文头 header_bytes = recv_all(client, 6) if not header_bytes: print("连接断开,头部接收失败") exit() body_len = int(header_bytes.decode('utf-8')) # 接收对应长度的图片二进制数据 img_bytes = recv_all(client, body_len) if not img_bytes or len(img_bytes) != body_len: print("图片数据接收不完整") exit() # 解码渲染图片 nparr = np.frombuffer(img_bytes, np.uint8) frame = cv2.imdecode(nparr, cv2.IMREAD_ANYCOLOR) if frame is None: print("图片解码失败") else: cv2.imshow('frame', frame) cv2.waitKey(1) # 必须加waitKey才能正常渲染图像窗口
客户端注意事项
C#端使用的BeginWrite是异步写入接口,需要在回调中确认写入完成,避免数据未完全发送就释放资源导致传输截断:
stream.BeginWrite(buff, 0, buff.Length, ar => { stream.EndWrite(ar); // 确认写入完成后再执行后续逻辑 }, null);
快速验证方法
可以先将接收的二进制数据写入本地文件验证传输完整性:
with open("test.png", "wb") as f: f.write(img_bytes)
如果本地可以正常打开test.png,说明传输链路没问题,否则需要排查客户端编码、发送逻辑。
内容的提问来源于stack exchange,提问作者Telefrag
相关产品推荐
相关产品推荐

