版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第UnitySockect实现画面实时传输案例原理解析目录前言一、Socket通信原理二、画面传输设计1.逻辑设计图2.Unity服务端3.Unity客户端4.最终效果
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Socket通信原理
Socket是比较常用的一种通信方式。有关介绍可以点击查看Socket通信原理
二、画面传输设计
1.逻辑设计图
2.Unity服务端
首先创建一个Unity工程,然后新建Server场景,用于接受数据,展示画面。
然后再场景中创建一个RawImage并设置为全屏。
如图:
然后创建一个脚本,命名为UnityServer,再创建一个UnityServer.cs
在Start函数中创建Socket服务器,并开启一个线程用于接受数据。
这里要注意一点,不能在接受数据线程中处理数据,需要在主线程中进行处理。
因为Unity主线程里面的资源不允许其他线程进行访问。
在Update函数中处理数据,并展示图片。
UnityServer.cs代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.IO;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Threading;
usingUnityEngine;
usingUnityEngine.UI;
publicclassUnityServer:MonoBehaviour{
Socketsocket=null;
Threadthread=null;
byte[]buffer=null;
boolreceState=true;
intreadTimes=0;
publicRawImagerawImage;
privateQueuebyte[]datas;
voidStart(){
buffer=newbyte[1024*1024*10];
//创建服务器,以Tcp的方式
socket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
socket.Connect(IPAddress.Parse("7"),10002);
//开启一个线程,用于接受数据
thread=newThread(newThreadStart(Receive));
thread.Start();
datas=newQueuebyte[]
privatevoidReceive()
while(thread.ThreadState==ThreadState.Runningsocket.Connected)
//接受数据Buffercount是数据的长度
intcount=socket.Receive(buffer);
if(receStatecount0)
receState=false;
BytesToImage(count,buffer);
MemoryStreamms=null;
publicvoidBytesToImage(intcount,byte[]bytes)
ms=newMemoryStream(bytes,0,count);
datas.Enqueue(ms.ToArray());//将数据存储在一个队列中,在主线程中解析数据。这是一个多线程的处理。
readTimes++;
if(readTimes5000)
readTimes=0;
GC.Collect(2);//达到一定次数的时候,开启GC,释放内存
catch
receState=true;
voidUpdate()
if(datas.Count0)
//处理纹理数据,并显示
Texture2Dtexture2D=newTexture2D(Screen.width,Screen.height);
texture2D.LoadImage(datas.Dequeue());
rawImage.texture=texture2D;
voidOnDestroy()
if(socket!=null)
socket.Shutdown(SocketShutdown.Both);
catch{}
if(thread!=null)
thread.Abort();
catch{}
datas.Clear();
}
然后在场景中创建一个GameObject,将脚本挂载上,并将创建的RawImage拖拽到Inspector面板上对应的位置。
如图:
3.Unity客户端
然后我们创建一个客户端工程,创建一个Client场景。
选中MainCamera,用Ctrl+D复制一个摄像机,放在MainCamera下面。
设置localPosition和localRotation为零。
这个相机的主要作用抓取屏幕渲染纹理。
如图:
然后再创建一个脚本,命名为UnityClient.cs脚本。在Start中开启Socket,然后开启一个线程发送数据。
将其挂载在MainCamera上面,并将渲染摄像机拖拽到相应的位置。
UnityClient.cs代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Threading;
usingUnityEngine;
publicclassUnityClient:MonoBehaviour{
publicCameracam;
publicintport=10002;
RenderTexturecameraView=null;
Socketsocket=null;
Threadthread=null;
boolsuccess=true;
Dictionarystring,Clientclients=newDictionarystring,Client
Vector3old_position;//旧位置
Quaternionold_rotation;//旧旋转
voidStart(){
cameraView=newRenderTexture(Screen.width,Screen.height,24);
cameraView.enableRandomWrite=true;
cam.targetTexture=cameraView;
old_position=transform.position;
old_rotation=transform.rotation;
//开启Socket
socket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
socket.Bind(newIPEndPoint(IPAddress.Parse("7"),port));
socket.Listen(100);
//开启一个线程发送渲染数据
thread=newThread(newThreadStart(OnStart));
thread.Start();
intisNewAdd=0;
voidOnStart()
Debug.Log("Socket创建成功");
while(thread.ThreadState==ThreadState.Running)
Socket_socket=socket.Accept();
if(clients.ContainsKey(_socket.RemoteEndPoint.ToString()))
clients[_socket.RemoteEndPoint.ToString()].socket.Shutdown(SocketShutdown.Both);
catch
clients.Remove(_socket.RemoteEndPoint.ToString());
Clientclient=newClient
socket=_socket
clients.Add(_socket.RemoteEndPoint.ToString(),client);
isNewAdd=1;
voidUpdate()
if(successclients.Count0)
success=false;
SendTexture();
if(isNewAdd0)
isNewAdd=0;
SendTexture(1);
voidOnGUI()
GUI.DrawTexture(newRect(10,10,240,135),cameraView,ScaleMode.StretchToFill);
voidOnApplicationQuit()
socket.Shutdown(SocketShutdown.Both);
catch{}
thread.Abort();
catch{}
Texture2DscreenShot=null;
intgc_count=0;
voidSendTexture(intisInt=0)
if((!old_position.Equals(transform.position)||!old_rotation.Equals(transform.rotation))||isInt==1)
if(null==screenShot)
screenShot=newTexture2D(Screen.width,Screen.height,TextureFormat.RGB24,false);
//读取屏幕像素进行渲染
RenderTexture.active=cameraView;
screenShot.ReadPixels(newRect(0,0,cameraView.width,cameraView.height),0,0);
RenderTexture.active=null;
byte[]bytes=screenShot.EncodeToJPG(100);
foreach(varvalinclients.Values)
val.socket.Send(bytes);
catch
if(!val.socket.Connected)
clients.Remove(val.socket.RemoteEndPoint.ToString());
gc_count++;
if(gc_count5000)
gc_count=0;
GC.Collect(2);
Debug.Log("发送数据:"+(float)bytes.Length/1024f
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024-2025学年全国统考教师资格考试《教育教学知识与能力(小学)》练习题审定版附答案详解
- 2024-2025学年度宝鸡职业技术学院单招《语文》综合提升测试卷附参考答案详解【综合题】
- 2024-2025学年农村信用社招聘考试题库试题(精练)附答案详解
- 2024-2025学年度执业兽医测试卷及参考答案详解(综合卷)
- 2024-2025学年度施工员模拟题库含答案详解AB卷
- 2024-2025学年度监理工程师全真模拟模拟题及完整答案详解【名校卷】
- 2024-2025学年度天津城市建设管理职业技术学院单招数学练习题及参考答案详解【研优卷】
- 2024-2025学年度计算机四级考前冲刺练习题及参考答案详解(研优卷)
- 2024-2025学年度广东环境保护工程职业学院妇产护理期末模拟试题带答案详解(突破训练)
- 企业资产完备无损承诺书(6篇)
- 汽轮机组试车方案
- 漆安慎力学第二版课后习题解答及漆安慎-力学答案
- PCI围术期强化他汀治疗的获益和机制课件
- 沥青搅拌站安全生产风险分级管控体系方案资料(2022-2023版)
- WTO海关估价协议中文版
- 【广东省】工作证明模板(仅供参考)
- YS/T 613-2006碳膜电位器用电阻浆料
- GB/T 33365-2016钢筋混凝土用钢筋焊接网试验方法
- GB/T 17626.10-2017电磁兼容试验和测量技术阻尼振荡磁场抗扰度试验
- GB/T 14536.6-2008家用和类似用途电自动控制器燃烧器电自动控制系统的特殊要求
- 《乡风文明建设》(王博文)
评论
0/150
提交评论