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;
}
}
}