Unity3D通过Socket向Python传实时摄像头图像字节数不匹配求助
问题核心原因
- 服务端存在致命逻辑错误:
Encoding.ASCII.GetBytes(image_bytes.ToString())行完全错误,C#中字节数组的默认ToString()方法输出的是System.Byte[]字符串,长度刚好为13个字符,所以客户端仅收到13字节,根本没有传输实际图像数据。 - 未处理TCP流边界问题:TCP是流式传输协议,没有数据边界,不提前约定数据长度的情况下,客户端无法判断一帧图像的接收范围,会出现半包、粘包问题。
- 客户端逻辑错误:二进制图像数据无需用UTF-8解码为字符串,直接保留二进制格式即可做后续图像处理。
修复方案
服务端(C#)修改
调整SendImageByte方法,先发送4字节的图像长度头,再发送原始图像二进制数据:
private void SendImageByte() { image_bytes = cm.Capture(); print(image_bytes.Length); if (connectedTcpClient == null || !connectedTcpClient.Connected) { return; } try { NetworkStream stream = connectedTcpClient.GetStream(); if (stream.CanWrite) { // 发送4字节的图像长度标记,方便客户端识别数据边界 byte[] lengthBytes = BitConverter.GetBytes(image_bytes.Length); stream.Write(lengthBytes, 0, lengthBytes.Length); // 直接发送原始图像二进制,无需做编码转换 stream.Write(image_bytes, 0, image_bytes.Length); Debug.Log($"图像发送完成,长度:{image_bytes.Length}"); } } catch (SocketException socketException) { Debug.Log("Socket异常: " + socketException); connectedTcpClient.Close(); connectedTcpClient = null; } }
客户端(Python)修改
新增定长接收方法,先读取4字节长度头,再按长度接收完整图像数据:
import socket import struct import io # 可引入PIL/OpenCV做后续图像解析,示例可选 # from PIL import Image # import cv2 # import numpy as np host = "127.0.0.1" port = 1755 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) def receive_all(target_len): """ 解决TCP半包问题,确保接收指定长度的字节数据 """ received_buf = b'' remaining_len = target_len while remaining_len > 0: chunk = sock.recv(remaining_len) if not chunk: return None received_buf += chunk remaining_len -= len(chunk) return received_buf def receive_image(): # 先读取4字节的图像长度头 length_data = receive_all(4) if not length_data: return image_len = struct.unpack('!I', length_data)[0] # 按长度接收完整图像二进制 image_data = receive_all(image_len) print(f"图像接收完成,长度:{image_len}") # 后续图像处理示例:解析为OpenCV格式 # nparr = np.frombuffer(image_data, np.uint8) # img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) # cv2.imshow("received image", img) # cv2.waitKey(1) while True: receive_image()
实时传输优化建议
- 若要降低延迟,可将Unity端的
EncodeToPNG()替换为EncodeToJPG(质量值),调整质量参数平衡画质和数据体积,提升传输效率 - 可添加简单的校验位逻辑,避免网络波动导致的传输出错
- 补充两端的断开重连逻辑,提升稳定性
内容的提问来源于stack exchange,提问作者Alvin
相关产品推荐
相关产品推荐

