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
{
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";
public int port = 56789;
private string preMsg = " ";
bool needReconnect = false;
public UnityEvent tcp发送事件;
public UnityEvent Tcp发送事件 => tcp发送事件;
private void Start()
{
Invoke("Client", 1f);
}
private void Update()
{
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);
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;
Send("Receive Message");
socket.ReceiveAsync(e);
}
else if (e.BytesTransferred == 0)
{
if (e.SocketError == SocketError.Success)
{
Debug.Log("主动断开连接 ");
}
else
{
Debug.Log("被动断开连接 ");
}
needReconnect = true;
}
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
private IPAddress getIdAddress()
{
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;
}
}
return ipAddr;
}
}
}
|