You need to enable JavaScript to run this app. Unity3D通过Socket向Python传实时摄像头图像字节数不匹配求助
优惠活动
大模型
产品
解决方案
定价
更多

Unity3D通过Socket向Python传实时摄像头图像字节数不匹配求助

问题核心原因
  1. 服务端存在致命逻辑错误:Encoding.ASCII.GetBytes(image_bytes.ToString()) 行完全错误,C#中字节数组的默认ToString()方法输出的是System.Byte[]字符串,长度刚好为13个字符,所以客户端仅收到13字节,根本没有传输实际图像数据。
  2. 未处理TCP流边界问题:TCP是流式传输协议,没有数据边界,不提前约定数据长度的情况下,客户端无法判断一帧图像的接收范围,会出现半包、粘包问题。
  3. 客户端逻辑错误:二进制图像数据无需用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 12:09:02