You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中UDP接收字节数据渲染RawImage失败求助

Unity UDP接收图片字节无法渲染RawImage问题解决

问题描述

在Unity中通过UDP连接接收图片字节数据,目标是渲染到RawImage组件中。从本地磁盘读取图片字节能正常渲染,但通过UDP接收的数据却无法显示,已确认接收的字节可转换为字符串(仅用于确认收到数据,字符串为乱码)。

原代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Text;
using System.Net;
using System.Net.Sockets;

public class Image : MonoBehaviour  
{
    // Start is called before the first frame update
    public RawImage image;
    UdpClient client;
    private RenderTexture renderTexture;
    float interval = 0.05f;
    float nextTime = 0;
    private int count;
    void Start()
    {
        count = 0;
        client = new UdpClient(8000);

    }

    //Update is called once per frame
    void Update()
    {
        //if (Time.time >= nextTime)
        //{
        //    Texture2D texture = new Texture2D(2, 2);
        //    string path = "C:/Users/Desktop/frames20/frame_" + count.ToString() + ".jpg";
        //    byte[] imageData = File.ReadAllBytes(path);
        //    texture.LoadImage(imageData);
        //    image.texture = texture;
        //    Debug.Log(path);
        //    //Destroy(texture);
        //    nextTime += interval;
        //    count += 1;
        //}

        if (client.Available > 0)
        {
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
            byte[] data = client.Receive(ref endPoint);
            string text = Encoding.UTF8.GetString(data);
            Debug.Log(text);
            if (data != null)
            {
                Texture2D texture = new Texture2D(2, 2);
                texture.LoadImage(data);
                image.texture = texture;
            }
        }
    }
}

问题原因分析

  1. UDP接收阻塞主线程:client.Receive()是同步阻塞方法,在Update中调用会卡住主线程,导致UI渲染不及时。
  2. 图片数据完整性问题:UDP单包最大仅支持约64KB(65507字节),若图片超过这个大小,数据会被截断,导致LoadImage失败。
  3. 错误的调试方式:用Encoding.UTF8.GetString(data)转换图片二进制数据为字符串,会破坏二进制完整性,且输出的乱码无法反映真实数据状态。
  4. 未检查加载结果:LoadImage返回bool值表示加载是否成功,原代码未做判断,无法排查加载失败原因。

解决代码及步骤

修改后的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class ImageReceiver : MonoBehaviour  
{
    public RawImage image;
    UdpClient client;
    Thread receiveThread;
    private byte[] receivedData;
    private bool hasNewData = false;

    void Start()
    {
        client = new UdpClient(8000);
        // 开启后台线程处理UDP接收,避免阻塞主线程
        receiveThread = new Thread(ReceiveUDPData);
        receiveThread.IsBackground = true;
        receiveThread.Start();
    }

    void ReceiveUDPData()
    {
        IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
        while (true)
        {
            try
            {
                receivedData = client.Receive(ref endPoint);
                hasNewData = true;
                // 打印数据长度而非转换为字符串,避免破坏二进制数据
                Debug.Log($"收到UDP数据,长度:{receivedData.Length}字节");
            }
            catch (SocketException e)
            {
                Debug.LogError($"UDP接收异常:{e.Message}");
                break;
            }
        }
    }

    void Update()
    {
        if (hasNewData && receivedData != null)
        {
            hasNewData = false;
            Texture2D texture = new Texture2D(2, 2);
            // 检查图片加载是否成功
            bool loadSuccess = texture.LoadImage(receivedData);
            if (loadSuccess)
            {
                image.texture = texture;
                Debug.Log("图片渲染成功");
            }
            else
            {
                Debug.LogError("图片加载失败,请检查数据完整性或格式");
            }
        }
    }

    void OnDestroy()
    {
        // 销毁时关闭线程和UDP客户端,避免资源泄漏
        if (receiveThread != null && receiveThread.IsAlive)
        {
            receiveThread.Abort();
        }
        client?.Close();
    }
}

额外注意事项

  • 大图片分包处理:若图片超过64KB,发送端需要将图片字节拆分多个UDP包发送,接收端需重组完整字节数组后再调用LoadImage。
  • 确认发送数据格式:确保发送端发送的是原始图片二进制数据,而非Base64编码字符串(若为Base64,接收端需先调用Convert.FromBase64String解码)。
  • 数据完整性校验:可以在发送端添加数据长度校验,接收端对比实际接收长度和预期长度,确认数据未丢失。

内容的提问来源于stack exchange,提问作者Rushikesh Nalamothu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:37:48