Unity实现Tcp通信

项目场景:

一个飞屏项目,两台主机使用tcp协议通信。控制端为服务器,发送控制信号,发送图片;大屏端为客户端,接收控制信号展示内容,接收图片并展示。


问题描述

  1. 只有先打开服务器再打开客户端,才能正确连接通信。
  2. 图片传输过去是乱码,不能正确显示。

原因分析:

  1. tcp脚本通信连接相关逻辑是单次连接,没有考虑周全。
  2. 图片数据很长,客户端接收数据不全。


解决方案:

  1. 客户端脚本《TcpClient》添加连接失败后等待10秒后重试。
  2. 服务器发送图片时先发送图片数据长度再发送图片数据,客户端根据图片数据长度接收完整数据,再根据头字节判定是否是图片。

 代码示例1:

 private async void StartClient()
    {
        if (!isRunning)
        {
            Debug.Log("客户端已停止运行,不再尝试连接");
            return;
        }
        Debug.Log("启动客户端" + ConfigMgr.Instance.baseConfig.IP地址);
        //服务器地址
        IPAddress ip = IPAddress.Parse(ConfigMgr.Instance.baseConfig.IP地址);
        IPEndPoint ipEnd = new IPEndPoint(ip, ConfigMgr.Instance.baseConfig.监听端口);
        clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        bool connected = await ConnectAsync(clientSocket, ipEnd);
        if (connected)
        {
            clientThread = new Thread(ClientThread);
            clientThread.Start();
        }
        else
        {
            Debug.LogError("连接失败,10秒后重试");
            await Task.Delay(10000); // 等待10秒后重试
            StartClient();
        }
    }

    private Task<bool> ConnectAsync(Socket socket, IPEndPoint endPoint)
    {
        return Task.Run(() =>
        {
            try
            {
                socket.Connect(endPoint);
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError("连接失败: " + ex.Message);
                return false;
            }
        });
    }

代码示例2:

《TcpClient.cs》

 //接收数据并校验
private byte[] ReceiveDataWithLength(Socket client)
    {
        // 接收数据长度
        byte[] lengthBytes = new byte[sizeof(int)];
        int receivedLength = 0;
        while (receivedLength < lengthBytes.Length)
        {
            int bytesReceived = client.Receive(lengthBytes, receivedLength, lengthBytes.Length - receivedLength, SocketFlags.None);
            if (bytesReceived == 0)
            {
                throw new SocketException(); // 连接可能已关闭
            }
            receivedLength += bytesReceived;
        }

        int dataLength = BitConverter.ToInt32(lengthBytes, 0);

        // 检查数据长度是否合理
        if (dataLength < 0 || dataLength > 1024 * 1024 * 10) // 假设最大数据长度为10MB
        {
            throw new OverflowException("接收到的数据长度不合理");
        }

        // 接收数据
        byte[] data = new byte[dataLength];
        receivedLength = 0;
        while (receivedLength < dataLength)
        {
            int bytesReceived = client.Receive(data, receivedLength, dataLength - receivedLength, SocketFlags.None);
            if (bytesReceived == 0)
            {
                throw new SocketException(); // 连接可能已关闭
            }
            receivedLength += bytesReceived;
        }
        Debug.Log("接收数据: " + dataLength + "," + data);

        return data;
    }

 if (fileHead == "255216" || fileHead == "13780")
        {
            //Debug.Log("是图片");
            return true;
        }
        else
        {
            //Debug.Log("不是图片");
            return false;
        }

《TcpServer.cs》

 // 发送RawImage图片(需要在“纹理导入设置”中使此纹理可读)
    public void SendTexture(RawImage rawImage)
    {
        try
        {
            // 获取RawImage的Texture2D
            Texture2D tex = rawImage.texture as Texture2D;
            if (tex == null)
            {
                Debug.LogError("RawImage的texture不是Texture2D类型");
                return;
            }

            // 获取Texture2D的bytes数据
            //byte[] textureBytes = tex.EncodeToPNG(); 

            // 创建一个新的Texture2D来存储未压缩的纹理数据
            Texture2D uncompressedTex = new Texture2D(tex.width, tex.height, TextureFormat.RGBA32, false);
            uncompressedTex.SetPixels(tex.GetPixels());
            uncompressedTex.Apply();

            // 获取未压缩Texture2D的bytes数据
            byte[] textureBytes = uncompressedTex.EncodeToJPG(); 

            // 将图片数据发送给客户端
            SendDataWithLength(client, textureBytes);
            Debug.Log("图片数据长度: " + textureBytes.Length);
        }
        catch (Exception ex)
        {
            Debug.LogError("发送图片时出错: " + ex.Message + "\n" + ex.StackTrace);
        }
    }

     private void SendDataWithLength(Socket client, byte[] data)
    {
        try
        {
            // 发送数据长度
            byte[] lengthBytes = BitConverter.GetBytes(data.Length);
            client.Send(lengthBytes);

            // 发送数据
            int bytesSent = client.Send(data);
            if (bytesSent == data.Length)
            {
                Debug.Log("服务器发送消息成功");
            }
            else
            {
                Debug.LogError("服务器发送消息失败");
            }
        }
        catch (Exception ex)
        {
            Debug.LogError("发送数据时出错: " + ex.Message + "\n" + ex.StackTrace);
        }
    }

UNITY-网络通信(TCP/UDP) 学习笔记 以后复习使用 阅读详情

相关推荐

unity使用Tcp/UDP协议网络通信实现(Socket简单应用)

服务器端: 1.打开vs,创建一个c#的控制台应用程序 代码如下 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using System.Net; namespace Socket服务器端 { class Program { static

梦想是世界和平 5027

【Unity】Socket网络通信(TCP) - 实现简单的多人聊天功能

unity实现非常简单的多人聊天功能,内含工程文件下载地址,免积分下载!

weixin_43453797的博客 9150

Unity HoloLens Socket通信实战:从UWP平台特性到TCP/UDP实现

Socket通信是网络编程的基础,它允许不同设备间建立可靠的数据通道。其核心原理是通过TCP或UDP协议在IP网络上进行端到端数据传输,TCP保证可靠有序,UDP则侧重低延迟。在混合现实(MR)与工业AR场景中,稳定的网络通信是实现设备状态同步、实时数据拉取与多用户协同的技术基石。针对HoloLens这类UWP平台设备,开发者需遵循其沙箱安全模型,在应用清单中声明网络能力,并采用异步编程模式避免阻塞主线程。本文聚焦Unity开发环境,详解如何利用StreamSocket构建TCP客户端,处理JSON序列化与

weixin_29279101的博客 312

【Unity】网络通信(TCP&UDP)

Socket 接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,用以开发TCP/IP网络上的应用程序。也就是说Socket是TCP/UDP通讯的实现方式。TCP和UDP是传输层协议,使用IP协议从一个网络传送数据包到另一个网络。把IP想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。两者的不同是:TCP能提供有保证的数据传输,而UDP不提供,即UDP的数据容易丢失。

DevFrank的博客 1万+

从零开始:用ROS-TCP-Endpoint实现Unity与ROS的双向通信(含完整代码示例)

本文详细介绍了如何利用ROS-TCP-Endpoint和ROS-TCP-Connector构建Unity与ROS之间的双向通信桥梁。通过环境配置、消息定义、代码实战等步骤,手把手教你实现虚拟环境与机器人算法的数据交互,为机器人仿真、数字孪生等应用提供稳定高效的通信解决方案。

weixin_29015127的博客 284

C#实现Unity中TCP通信的本地服务器与客户端

传输控制协议(TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它由互联网工程任务组(IETF)在RFC 793中定义,是互联网中最重要的协议之一。TCP确保数据包能够在复杂的网络环境中准确无误地到达目的地,它在数据发送前会建立一个连接,并在数据传输完成后断开连接。在 .NET Framework 中,命名空间提供了许多用于网络通信的类。这些类允许开发者编写能够执行各种网络操作的程序,如发送和接收数据,建立连接,和在客户端与服务器之间进行通信。

weixin_32747681的博客 1227

在Unity中实现TCP通信(附完整工程)

本篇博客讲述了如何在unity中实现简单的TCP通信功能,包含服务器端与客户端,并配有简易的交互界面,用来显示一些状态信息以及接收和发送的数据。

qq_39748832的博客 2万+

Unity 网络 之 TcpListener 实现简单的网络服务器和客户端通讯功能封装(可监听多个客户端).rar

Unity 网络 之 TcpListener 实现简单的网络服务器和客户端通讯功能封装(可监听多个客户端) 在Unity中用 TcpClient、TcpListener 两个封装类和 NetworkStream 来实现一个简单的网络通讯 demo 实现原理 1、首先通过 IP 和 端口号,开启服务器监听 2、在客户端连接进入之后,会开启一个线程维持与该客户端的通讯,处理该客户端的消息 3、在异步开启一个监听,继续监听客户端接入,如此反复,实现无限(理论上)监听 4、客户端连接服务器,然后开线程,维持与该服务器的通讯,处理服务器的消息

tcp unity 图片_unity做客户端实现TCP网络通信

unity开发:Qt C++与unity之间TCP网络通信考虑实现用C++做服务器,unity做客户端实现TCP网络通信。以下采用TCP单线程连接。Qt C++服务端建立一个Qt的GUI项目,在界面上放一个label显示连接状态,两个button作为指令发送控制。记得在pro文件中加入network模块widget.h#ifndef WIDGET_H#define WIDGET_H#include...

weixin_39586649的博客 376

【Qt】QByteArray详解

对象共享同一份数据,直到修改时才进行深拷贝,以节省内存和计算资源。:可存储任意二进制数据(如图片、音频、协议数据),不依赖字符编码。与编码(如 UTF-8、Latin-1)之间的桥梁(例如。• 补零规则确保奇数字符串能正确解析,避免数据截断。:内部自动分配和释放内存,无需手动管理。将输入的字符串视为十六进制编码数据,返回实际数据长度(不包括结尾的。的输入必须是有效的十六进制字符(,但针对 Qt 框架做了优化。:处理加密后的二进制结果(如。• 如果输入字符串长度为奇数,• 若输入长度为奇数,自动在。

CSUC的博客 1597

从收音机到Arduino:手把手教你用BJT三极管搭建一个简易音频放大器(附电路图与元件清单)

本文详细介绍了如何使用BJT三极管搭建简易音频放大器,涵盖电路原理、元件选择、设计步骤及调试技巧。通过实践项目帮助电子爱好者深入理解BJT的放大特性,并提供与Arduino结合的扩展应用方案,适合创客和DIY玩家。

aitie1479的博客 437

在Unity中轻松实现TCP通信:一个完整的开源解决方案

在Unity中轻松实现TCP通信:一个完整的开源解决方案 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在游戏开发和虚拟现实应用中,实时通信是不可或缺的一部分。为了帮助开发者更轻松地在Unity中实现TCP通信,我们推出了一款开源项目——Unity TCP通信实现。该项目提供了一个完整的Unity工程,包含了服务器端和客户端的实现,并配备了简易的交互界面,方便开发者快...

gitblog_06511的博客 640

在 Ubuntu 上安装和配置 PostgreSQL 实录

本文介绍了在Ubuntu系统上安装和配置PostgreSQL数据库的完整步骤。主要内容包括:1)通过官方源或PPA源安装最新版本;2)修改配置文件(postgresql.conf和pg_hba.conf)以允许远程访问;3)设置postgres用户密码;4)创建新用户并配置权限;5)防火墙设置和重启服务;6)验证安装和远程连接方法。文章提供了详细的命令行操作指导,帮助用户完成从安装到远程访问的全部配置过程。

qq_58168857的博客 1204

Unity网络通信实战:TCP与UDP实现

通过以上内容,可以构建基础的Unity网络通信功能。实际开发中需要考虑更多因素如安全性、协议设计、流量控制等。建议从简单功能开始,逐步扩展为完整的网络系统。在网络通信中,复杂数据结构需要序列化为字节流进行传输。常用的序列化方法有JSON和二进制序列化。TCP是一种面向连接的协议,提供可靠的数据传输。在Unity中实现TCP通信需要使用。UDP是一种无连接的协议,传输速度快但不保证可靠性。完善的网络程序需要处理各种异常情况,如连接超时、数据丢失等。

2501_94130865的博客 467

睿尔曼复合机器人之底盘操作流程

控制键”按下后,可在键盘上通过‘i’(向前),‘k’(向后),‘j’(向左旋转),‘l’(向右旋转)四个按键对底盘进行运动控制。选中禁⾏线功能后,使⽤⿏标在界⾯内点击选择起点,继续在其他地⽅点击,两点之间会连成⼀条线,可以进⾏多次连续点击,形成连续线条。4)扫图完成后,软件会重新启动,返回到监控页面,点击“激光”可看到当前机器激光扫描的实时数据,在页面上表现为红色边界线,点击菜单栏“控制”键使底盘在一定范围内运动,扫描到尽可能多的边界线,可发现与实际地图的黑色边界线不同,需要进行手动校正。

realman_Rop的博客 1474

黑群晖DSM7.0.1物理机安装教程

使用芯片无忧工具,查看U盘的和。使用,格式化U盘。使用镜像写入工具,把引导写入U盘。修改文件,可以使用工具把文件复制到桌面,通过修改好之后,拖进这个界面中。或者在电脑中,查看U盘,打开U盘中的文件直接修改。具体修改内容如下:PID修改为U盘的PIDVID修改为U盘的VID默认只有mac1=a8412083CB52 mac2=0a11323D47F7 ,增加:mac3=a15823C08000 mac4=a23C04158B52 mac5=82a002524158 mac6=38233052415aS

JingLisen的博客 2万+

【亲测免费】 在Unity中实现TCP通信(附完整工程)

在Unity中实现TCP通信(附完整工程) 去发现同类优质开源项目:https://gitcode.com/ 概述 本资源文件提供了一个完整的Unity工程,展示了如何在Unity中实现TCP通信。该工程包含服务器端和客户端的实现,并配有简易的交互界面,用于显示状态信息以及接收和发送的数据。 主要功能 服务器端: 初始化套接字(Socket)并绑定IP地址和端口号。 创建子线程监听客户端连接...

gitblog_06569的博客 474

博途V17 & PLCSIM & FactoryIO 连接教程

PLCSIM V17 和 FactoryIO 连接教程前言一、软件版本二、连接步骤1. 连接PLCSIM2. 博途编程3.连接FactoryIO总结 前言 该文详细讲解了新手入门博途,并通过使用自带PLCSIM和FactoryIO实现连接。 一、软件版本 TIA Portal V17 S7-PLCSIM V17 Factory IO V2.5.1 二、连接步骤 1. 连接PLCSIM 打开PLCSIM 进入项目模式 新建仿真项目 2. 博途编程 将F

soledad_chao的博客 2万+

Unity HTFramework网络模块入门:Network实现TCP/UDP通信

Unity HTFramework是一款基于Unity的客户端快速开发框架,其网络模块(Network)提供了便捷的TCP/UDP通信实现方案,帮助开发者轻松构建稳定高效的网络连接。本文将带您快速掌握HTFramework网络模块的核心功能和使用方法,实现客户端与服务器的可靠通信。 ## 网络模块核心组件解析 HTFramework的网络功能主要通过`NetworkManager`类实现,该类

gitblog_01047的博客 440

非易失存储器读写

24C256、IIC_SCL、IIC_SDA

CT_1104的专栏 2985

手把手教你学 GPU KMD”相关内容的专栏简介与目录

本专栏系统讲解GPU内核模式驱动(KMD)开发技术,涵盖四大核心模块:1)GPU驱动架构基础,解析UMD/KMD协同机制;2)KMD核心功能,包括内存管理、命令提交、中断处理等;3)底层硬件交互,详解PCIe/DMA传输、多级页表等;4)实战进阶,结合Linux DRM框架代码分析,探讨GPU虚拟化与性能优化。面向具备OS和C语言基础的开发者,提供从理论到实践的完整学习路径,帮助深入理解图形/计算驱动栈的底层实现原理。

amy_mhd的博客 153

【Unity】简单实现基于TCP的阻塞式Socket的文本消息通信

本文介绍了一种在Unity运行的简单可行的基于TCP的阻塞式Socket的文本消息通信的示例

qq_47009853的博客 513

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

unity调用dll 实现非阻塞socket server 的tcp 网络通信

dll端的代码 #include "TcpSrv.h" #pragma comment(lib,"ws2_32.lib") static SOCKET sServer = INVALID_SOCKET; static SOCKET sClient = INVALID_SOCKET; int InitSrv(int ip, int port) { WSADATA wsd; int ret...

ljxh401的博客 623

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Unity网络编程入门:基于TCP阻塞式Socket实现文本消息通信

网络通信是现代软件开发的基础能力,尤其在游戏和实时应用中,TCP协议因其可靠的数据传输特性成为首选。TCP通过三次握手建立连接,并采用确认应答、超时重传等机制确保数据有序、无差错到达,这种面向连接的字节流协议非常适合对可靠性要求高的场景,如文本消息传输。在Unity开发中,直接使用System.Net.Sockets进行TCP通信,能帮助开发者深入理解网络底层原理,掌握数据流的处理方式。然而,TCP的字节流特性会导致“粘包”问题,需要通过应用层协议界定消息边界,常见的分隔符法(如换行符)简单高效,是文本通信

weixin_29011667的博客 281

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Unity集成NModbus4实现Modbus TCP通信:工业仿真与数字孪生实战指南

Modbus TCP作为一种广泛应用于工业自动化领域的开放式通信协议,其核心原理是基于客户端/服务器模型,通过功能码和寄存器地址实现对PLC、传感器等现场设备的标准化数据读写。这项技术的核心价值在于打通了信息层与控制层,为设备监控、数据采集和系统集成提供了统一接口。在工业仿真、数字孪生和可视化监控等应用场景中,将Modbus TCP通信能力集成到实时3D开发环境成为关键需求。Unity引擎凭借其强大的实时渲染和交互能力,结合NModbus4这一成熟的开源C#库,能够高效构建连接虚拟世界与物理设备的通信桥梁。

weixin_33860528的博客 404

unity下tcp协议socket异步通信,服务端和客户端代码实现

unity下tcp协议socket异步通信,服务端和客户端代码实现 .Net APISocket类 https://docs.microsoft.com/zh-cn/dotnet/api/system.net.sockets.socket?view=netframework-4.7.2 服务端部分: 服务端的流程是:绑定IP和端口-》监听-》接收连接,有客户端连上后,服务端对该客户...

weixin_30467087的博客 446
上一篇: Unity一个项目每次打开一个U3D的脚本,都会自动重新打开一个新的VS窗口
下一篇: Unity触屏项目踩坑
LoadYa
博客等级 码龄8年 424粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值