Hololens2初入—— Unity socket 异步通讯

Hololens2初入——socket 异步通讯

介绍

Hololens2真机中运行的程序与在电脑端的程序要求有些不同。 它不支持同步的socket,必须采用异步的形式才能跑的通。具体的原因和细节我也没去研究过,不过记得在官网上确实提到过这一点。
下面是一段示例代码,忘了是不是从其他地方直接拷贝过来还是自己有稍微修改过了,时间有点长,也忘了参考的出处了,如果有侵犯问题请私信我。

把下面的代码复制到C#的脚本中, 脚本名称修改为TcpClient.cs,然后把这个脚本随意挂在某个对象上就可以。 这边的代码是客户端的代码,服务端的暂时忘了放在哪里了,找到再补上。
调式的话建议用一个网络调试助手小软件来调式。 网络调试助手中开启 服务端就可以。

有其他问题直接在文章下面询问, 这样其他人才能看得到,尽量不要私信我。

代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

namespace MyCode
{
     
    public class TcpClient : MonoBehaviour
    {
     
        //连接到Tcp客户端并能够收发信息,断线重连,将客户端发送过来的信息显示在debugText中
        //手机开热点服务器ip 172.20.10.1 (不一定是这个,从网络设置中查看)
        public Text debugText;
        public GameObject cube;
        public Socket m_socket;
        IPEndPoint m_endPoint;
        private SocketAsyncEventArgs m_connectSAEA;

        private SocketAsyncEventArgs m_sendSAEA;
        public string ip = "192.168.137.1";//改成自己的ip

        public int port = 56789;
        private string preMsg = " ";
        bool needReconnect = false;

        public UnityEvent  tcp发送事件;
        public UnityEvent  Tcp发送事件 => tcp发送事件;


        private void Start()
        {
     
            //Client();
            Invoke("Client", 1f);
        }
        private void Update()
        {
     

            // //接收信息的回调函数上无法处理与Unity直接相关部分,在这里进行修改
            // if (debugText && preMsg != " ") //接收消息
            // {
     
            //     //if (preMsg == "red")
            //     //{
     
            //     //    cube.GetComponent().material.color = Color.red;
            //     //    preMsg = "";
            //     //}
            //     //else if (preMsg == "green")
            //     //{
     
            //     //    cube.GetComponent().material.color = Color.green;
            //     //    preMsg = "";
            //     //}
            //     debugText.text = preMsg; //显示在Debug的UI上
            //     preMsg = " ";
            // }
            // //else
            // //{
     
            // //    cube.GetComponent().material.color = Color.yellow;
            // //}

            if (needReconnect) //处理断线重连
            {
     
                Invoke("Client", 5f);
                needReconnect = false;
            }
        }

        public void Client()
        {
     
            m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPAddress iPAddress = IPAddress.Parse(ip);
            // IPAddress iPAddress = getIdAddress();
            print(iPAddress.ToString());
            m_endPoint = new IPEndPoint(iPAddress, port);
            m_connectSAEA = new SocketAsyncEventArgs {
     RemoteEndPoint = m_endPoint};
            m_connectSAEA.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnectedCompleted);
            m_socket.ConnectAsync(m_connectSAEA);
        }

        private void OnConnectedCompleted(object sender, SocketAsyncEventArgs e)
        {
     
            if (e.SocketError != SocketError.Success)
            {
     
                needReconnect = true;
                return;
            }

            Socket socket = sender as Socket;
            string iPRemote = socket.RemoteEndPoint.ToString();
            Debug.Log("Client : 连接服务器" + iPRemote + "成功");

            SocketAsyncEventArgs receiveSAEA = new SocketAsyncEventArgs();
            byte[] receiveBuffer = new byte[1024 * 1024 * 16];
            receiveSAEA.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
            receiveSAEA.Completed += OnReceiveCompleted;
            receiveSAEA.RemoteEndPoint = m_endPoint;
            socket.ReceiveAsync(receiveSAEA);
        }

        private void OnReceiveCompleted(object sender, SocketAsyncEventArgs e)
        {
     
            if (e.SocketError == SocketError.OperationAborted) return;
            Socket socket = sender as Socket;
            if (e.SocketError == SocketError.Success && e.BytesTransferred > 0)
            {
     
                string ipAdress = socket.RemoteEndPoint.ToString();
                int lengthBuffer = e.BytesTransferred;
                byte[] receiveBuffer = e.Buffer;

                //读取指定位数的信息
                byte[] data = new byte[lengthBuffer];
                Array.Copy(receiveBuffer, 0, data, 0, lengthBuffer);
                string str = System.Text.Encoding.Default.GetString(data);
                string newstr = str;
                Debug.Log(newstr);
                preMsg = newstr; //这里直接赋值给debugText.text无法更新,通过update中检测的方式更新信息
                //向服务器端发送消息
                Send("Receive Message");
                socket.ReceiveAsync(e);
            }
            else if (e.BytesTransferred == 0) //连接断开的处理
            {
     
                if (e.SocketError == SocketError.Success)
                {
     
                    Debug.Log("主动断开连接 ");
                    //DisConnect();
                }
                else
                {
     
                    Debug.Log("被动断开连接 ");
                }

                needReconnect = true; //通过update中检测的方式更新信息
            }
            else
            {
     
                return;
            }
        }

        #region 发送

        public void Send(string msg)
        {
     
            byte[] sendBuffer = Encoding.Default.GetBytes(msg);
            if (m_sendSAEA == null)
            {
     
                m_sendSAEA = new SocketAsyncEventArgs();
                m_sendSAEA.Completed += OnSendCompleted;
            }

            m_sendSAEA.SetBuffer(sendBuffer, 0, sendBuffer.Length);
            if (m_socket != null)
            {
     
                m_socket.SendAsync(m_sendSAEA);
            }
        }

        void OnSendCompleted(object sender1, SocketAsyncEventArgs e1)
        {
     
            if (e1.SocketError != SocketError.Success) return;
            Socket socket1 = sender1 as Socket;
            byte[] sendBuffer = e1.Buffer;

            string sendMsg = Encoding.Default.GetString(sendBuffer);
            Debug.Log("Client : Send message" + sendMsg + "to Serer" + socket1.RemoteEndPoint.ToString());
        }

        #endregion

        #region 断开连接

        void DisConnect()
        {
     
            Debug.Log("断开连接");
            if (m_socket != null)
            {
     
                try
                {
     
                    m_socket.Shutdown(SocketShutdown.Both);
                }
                catch (SocketException excep)
                {
     
                }
                finally
                {
     
                    m_socket.Close();
                }
            }
        }

        #endregion

        //——————————2021-10-03———————#date#—————#time#—————————//
        private IPAddress getIdAddress()
        {
     
            //IPHostEntry ipEntity = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress ipAddr = ipEntity.AddressList[0];

            //IPAddress ipAddr = Dns.GetHostAddresses(Dns.GetHostName())[0];
            //if (ipAddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)//判断是否IP6协议
            //{
     
            //    ipAddr = Dns.GetHostEntry(Dns.GetHostName()).AddressList[1];
            //}
            IPAddress ipAddr = null;
            IPAddress[] arrIP = Dns.GetHostAddresses(Dns.GetHostName());
            foreach (IPAddress ip in arrIP)
            {
     
                if (System.Net.Sockets.AddressFamily.InterNetwork.Equals(ip.AddressFamily))
                {
     
                    ipAddr = ip; // IPV4
                }

                // else if (System.Net.Sockets.AddressFamily.InterNetworkV6.Equals(ip.AddressFamily))
                // {
     
                //     ipAddr = ip;
                // }
            }

            return ipAddr;
        }
    }
}

你可能感兴趣的