参考了http://t.csdnimg.cn/mwlJE
一、UDP是什么?
UDP(User Datagram Protocol)是一种无连接的传输层协议,它提供了一种简单的、不可靠的数据传输服务。
UDP 提供了不面向连接的通信,且不对传送的数据报进行可靠的保证,适用于一次传送少量的数据,不适用于传输大量的数据。
二、使用步骤
1.实现一个连接类
新建UDPManager脚本
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class UDPManager
{
public string recvStr; // 服务器返回的值
public string UDPClientAddRess = "192.168.110.114"; // 目标服务器地址
public int UDPClientPort = 7000; // 目标服务器端口号
Socket socket; // UDP套接字
EndPoint serverEnd;
IPEndPoint ipEnd;
byte[] recvData = new byte[1024]; // 用于接收数据的字节数组
byte[] sendData = new byte[1024]; // 用于发送数据的字节数组
int recvLen = 0;
Thread connectThread; // 用于接收数据的线程
/// <summary>
/// 创建服务器
/// </summary>
public void InitializeUdpClient()
{
UDPClientAddRess = UDPClientAddRess.Trim(); // 清除地址中的空白字符
ipEnd = new IPEndPoint(IPAddress.Parse(UDPClientAddRess), UDPClientPort); // 创建目标终结点
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // 创建UDP套接字
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
serverEnd = sender;
Debug.Log("服务器启动"); // 打印服务器启动日志
connectThread = new Thread(new ThreadStart(SocketReceve)); // 创建接收数据的线程
}
/// <summary>
/// 向服务器发送数据
/// </summary>
/// <param name="message">要发送的消息</param>
public void InitSocket(string message)
{
SocketSend(message); // 调用发送数据的方法
//Debug.Log("发送成功"); // 打印发送成功日志
if (connectThread.ThreadState != ThreadState.Running)
{
connectThread.Start(); // 启动接收数据的线程
}
}
/// <summary>
/// 向服务端发送需要发送的内容
/// </summary>
/// <param name="sendMessage">要发送的消息</param>
void SocketSend(string sendMessage)
{
// 首先清空数据
sendData = new byte[1024];
// 转换数据
sendData = Encoding.UTF8.GetBytes(sendMessage); // 将消息转换为字节数组
// 发送数据到服务端
socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
}
/// <summary>
/// 接收来自服务端的消息
/// </summary>
void SocketReceve()
{
while (true)
{
recvData = new byte[1024];
try
{
recvLen = socket.ReceiveFrom(recvData, ref serverEnd); // 从服务端接收数据
}
catch (System.Exception e)
{
Debug.LogError("出现异常,异常信息:" + e); // 打印接收数据异常
break; // 有异常时跳出循环
}
if (recvLen > 0)
{
recvStr = Encoding.UTF8.GetString(recvData, 0, recvLen); // 将接收到的字节数组转换为字符串
}
else
{
Debug.LogError("接收到的数据长度小于等于0,可能连接已断开"); // 打印接收数据长度小于等于0的错误日志
SocketQuit(); // 关闭套接字
break; // 跳出循环
}
}
}
/// <summary>
/// 关闭与服务器的连接
/// </summary>
public void SocketQuit()
{
Debug.Log("销毁UDP"); // 打印销毁UDP的日志
if (connectThread != null)
{
connectThread.Interrupt(); // 中断线程
connectThread.Abort(); // 终止线程
}
if (socket != null)
{
socket.Close(); // 关闭套接字
}
}
}
2.使用方法
将脚本挂载场景任一物体上。
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using UnityEngine.Video;
/// <summary>
/// 服务接收生成
/// </summary>
public class ServerControl : MonoBehaviour
{
public Text Text;//显示接收到的信号
UDPManager udpMgr;
// Start is called before the first frame update
void Start()
{
udpMgr = new UDPManager();
udpMgr.InitializeUdpClient();//创建服务器
}
private void Update()
{
if (udpMgr.recvStr != null)
{
if (udpMgr.recvStr.Contains("ok")) // 如果接收到的消息中包含 "ok"
{
if (Text.text != "指令执行结束")
{
Debug.Log("Received message containing 'ok'. Stopping further reception."); // 打印接收到包含 'ok' 的消息的日志
Text.text = "指令执行结束";
}
}
else
{
Text.text = "收到信息:" + udpMgr.recvStr.ToString();
isOk = false;
}
}
}
public void Send(string str)//发送信号
{
udpMgr.InitSocket(str);
Debug.Log("点位信号:" + str);
}
}
总结
需要注意协程开关问题,成功实现和硬件UDP通信,可发可接。