视频演示: https://live.csdn.net/v/414881?spm=1001.2014.3001.5501
基于System.Net.Socket和System.Net.Http均是可以实现的
在与HoloLens通讯过程中需要关闭Microsoft Defender防火墙,以System.Net.Socket为例,不然会报错SocketExpection. Connection Timed Out
如果有帮助记得点个赞
HoloLens与PC进行Socket通讯最好不采用UTF-8编码,自己定义编码及解码方式,这也是Socket通讯的优势
下面程序中is_xx是bool,谁要是想用下面的代码的话可以将第一段放在一个Button下面,同时取private bool is_socket = false;
传输矩阵或者数字的话可以直接用我的,若有其他需求可以自己定义自己的编码方式。
//这是第一段需要放在button下的
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
List<Socket> clientSocketsList = new List<Socket>();
if (!is_socket)
{
is_socket = true;
LogBox.AppendText("远程通讯中" + Environment.NewLine);
socket_conn.IconColor = Color.Red;
string IP = this.textBox1.Text;
int port = Convert.ToInt32(this.textBox2.Text);
IPAddress ip = IPAddress.Parse(IP);
IPEndPoint endPoint = new IPEndPoint(ip, port);
serverSocket.Bind(endPoint);
serverSocket.Listen(10);// 开始监听
LogBox.AppendText("服务器多线程已启动,正在监听HoloLens连接..." + Environment.NewLine);
//client_Socket = serverSocket.Accept();
new Thread(() =>
{
//client_Socket = serverSocket.Accept();// 等待客户端连接
while (true)
{
// 检查是否有已连接的客户端
if (serverSocket.Poll(0, SelectMode.SelectRead))
{
// 有新的客户端连接请求
Socket newtempSocket = serverSocket.Accept();
clientSocketsList.Add(newtempSocket);
LogBox.Invoke((MethodInvoker)delegate
{
LogBox.AppendText("新接入一个设备:" + newtempSocket.RemoteEndPoint.ToString()+ Environment.NewLine);
});
Console.WriteLine("新接入一个设备:" + newtempSocket.RemoteEndPoint.ToString());
}
for (int i = 0; i < clientSocketsList.Count; i++)
{
if (clientSocketsList[i].Poll(0, SelectMode.SelectRead))
{
LogBox.Invoke((MethodInvoker)delegate
{
LogBox.AppendText("断开入一个设备:" + clientSocketsList[i].RemoteEndPoint.ToString() + Environment.NewLine);
});
Console.WriteLine("断开入一个设备:" + clientSocketsList[i].RemoteEndPoint.ToString());
clientSocketsList[i].Shutdown(SocketShutdown.Both);
clientSocketsList[i].Close();
clientSocketsList.RemoveAt(i);
i--;
}
}
if (clientSocketsList.Count > 0)
{
try
{
pose ndipose = new pose();
if (is_CAM_socket_model)
{
ndipose.m00 = global_varible.CAM_postureMat4x4.M11;
ndipose.m01 = global_varible.CAM_postureMat4x4.M12;
ndipose.m02 = global_varible.CAM_postureMat4x4.M13;
ndipose.m03 = global_varible.CAM_postureMat4x4.M14;
ndipose.m10 = global_varible.CAM_postureMat4x4.M21;
ndipose.m11 = global_varible.CAM_postureMat4x4.M22;
ndipose.m12 = global_varible.CAM_postureMat4x4.M23;
ndipose.m13 = global_varible.CAM_postureMat4x4.M24;
ndipose.m20 = global_varible.CAM_postureMat4x4.M31;
ndipose.m21 = global_varible.CAM_postureMat4x4.M32;
ndipose.m22 = global_varible.CAM_postureMat4x4.M33;
ndipose.m23 = global_varible.CAM_postureMat4x4.M34;
ndipose.m30 = global_varible.CAM_postureMat4x4.M41;
ndipose.m31 = global_varible.CAM_postureMat4x4.M42;
ndipose.m32 = global_varible.CAM_postureMat4x4.M43;
ndipose.m33 = global_varible.CAM_postureMat4x4.M44;
}
if (is_NDI_socket_model)//优先传输NDI,同时打开覆盖CAM数据
{
ndipose.m00 = global_varible.NDI_posture.M11;
ndipose.m01 = global_varible.NDI_posture.M12;
ndipose.m02 = global_varible.NDI_posture.M13;
ndipose.m03 = global_varible.NDI_posture.M14;
ndipose.m10 = global_varible.NDI_posture.M21;
ndipose.m11 = global_varible.NDI_posture.M22;
ndipose.m12 = global_varible.NDI_posture.M23;
ndipose.m13 = global_varible.NDI_posture.M24;
ndipose.m20 = global_varible.NDI_posture.M31;
ndipose.m21 = global_varible.NDI_posture.M32;
ndipose.m22 = global_varible.NDI_posture.M33;
ndipose.m23 = global_varible.NDI_posture.M34;
ndipose.m30 = global_varible.NDI_posture.M41;
ndipose.m31 = global_varible.NDI_posture.M42;
ndipose.m32 = global_varible.NDI_posture.M43;
ndipose.m33 = global_varible.NDI_posture.M44;
}
byte[] tempbytes = new byte[1024];
tempbytes = StructToByte(ndipose);
for (int i = 0; i < clientSocketsList.Count; i++)//send data for all client device
clientSocketsList[i].Send(tempbytes);
LogBox.Invoke((MethodInvoker)delegate
{
LogBox.AppendText("Send Message +1" + Environment.NewLine);
});
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
this.Close();
for (int i = 0; i < clientSocketsList.Count; i++)//send data for all client device
clientSocketsList[i].Shutdown(SocketShutdown.Both);
for (int i = 0; i < clientSocketsList.Count; i++)//send data for all client device
clientSocketsList[i].Close();
}
}
else
{
}
}
}).Start();
}
else
{
//server_Socket = serverSocket.Accept();
LogBox.AppendText("已断开socket连接");
is_socket = false;
serverSocket.Close();
//SocketConnect.Text = "";
socket_conn.IconColor = Color.White;
//SocketConnect.ImageAlign = ContentAlignment.MiddleCenter;
}
同时复制下面程序到Button外:
public static byte[] StructToByte(pose poseData)
{
int size = Marshal.SizeOf(typeof(pose));
byte[] buffer = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(poseData, ptr, true);
Marshal.Copy(ptr, buffer, 0, size);
Marshal.FreeHGlobal(ptr);
return buffer;
}
public struct pose
{
public float m00;
public float m01;
public float m02;
public float m03;
public float m10;
public float m11;
public float m12;
public float m13;
public float m20;
public float m21;
public float m22;
public float m23;
public float m30;
public float m31;
public float m32;
public float m33;
}
--------------------------------分界线
在HoloLens端解码方式,和上面没关系了,创建一个scoket.cs脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System;
public class scoket : MonoBehaviour
{
[Header("Static")]
public static scoket client; //脚本内的全局变量
[Header("Network")]
private bool activeConnection = true; //判断是否尝试连接的变量
private Socket mClient;
public string mIp = "192.168.3.11"; //连接 IP
public int mPort = 8888; //连接端口
[HideInInspector] public pose ReceivedPose = new pose();
private IPEndPoint mServerIpEndPoint;
private bool is_connect2_pc = false;
private void Awake()
{
client = this;
}
public void Start()
{
if (activeConnection) //尝试连接
{
InitClient();
is_connect2_pc = true;
}
}
private void Update()
{
if (activeConnection)
{
Receive();
//
}
}
public void OnApplicationQuit()
{
is_connect2_pc = false;
CloseClient();
}
private void InitClient()
{
mServerIpEndPoint = new IPEndPoint(IPAddress.Parse(mIp), mPort);
mClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mClient.Connect(mServerIpEndPoint);
Debug.Log(mClient.RemoteEndPoint.ToString());
}
private void Receive()
{
if (is_connect2_pc)
{
int receive = 0;
//Debug.Log(mClient.Available);
if (mClient.Available != 0)//client.Available属性返回内部缓冲区中已接收但尚未读取的数据的字节数。
{
byte[] packet = new byte[1024];
try
{
receive = mClient.Receive(packet);//packet为接收包
}
catch (Exception)
{
return;
}
//mReceivePacket = ByteArrayToStruct<Packet>(packet); //存储数据包
ReceivedPose = ByteArrayToArrayStruct<pose>(packet); //存储数据包
Debug.Log("rows1:" + ReceivedPose.m00 + ";" + ReceivedPose.m01 + ";" + ReceivedPose.m02 + ";" + ReceivedPose.m03);
Debug.Log("rows2:" + ReceivedPose.m10 + ";" + ReceivedPose.m11 + ";" + ReceivedPose.m12 + ";" + ReceivedPose.m13);
Debug.Log("rows3:" + ReceivedPose.m20 + ";" + ReceivedPose.m21 + ";" + ReceivedPose.m22 + ";" + ReceivedPose.m23);
Debug.Log("rows4:" + ReceivedPose.m30 + ";" + ReceivedPose.m31 + ";" + ReceivedPose.m32 + ";" + ReceivedPose.m33);
}
else
{
Debug.Log("Receive Nothing");
}
}
}
private void CloseClient()
{
if (mClient != null)
{
mClient.Close();
mClient = null;
}
}
private T ByteArrayToStruct<T>(byte[] buffer) where T : struct
{
int size = Marshal.SizeOf(typeof(T));
if (size > buffer.Length)
{
throw new Exception();
}
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(buffer, 0, ptr, size);
T obj = (T)Marshal.PtrToStructure(ptr, typeof(T));
Marshal.FreeHGlobal(ptr);
return obj;
}
private T ByteArrayToArrayStruct<T>(byte[] buffer) where T : struct
{
int size = Marshal.SizeOf(typeof(T));
if (size > buffer.Length)
{
throw new Exception();
}
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(buffer, 0, ptr, size);
T obj = (T)Marshal.PtrToStructure(ptr, typeof(T));
Marshal.FreeHGlobal(ptr);
return obj;
}
}
public struct pose
{
public float m00;
public float m01;
public float m02;
public float m03;
public float m10;
public float m11;
public float m12;
public float m13;
public float m20;
public float m21;
public float m22;
public float m23;
public float m30;
public float m31;
public float m32;
public float m33;
}
如下图所示,在写这篇博客期间已测试半小时,可持续稳定实现数据传输
断开时可有消息提示