前言
上一篇《Unity3D网络通讯(四)--Socket通讯之Tcp通讯》我们把Tcp的通讯已经说完了,这篇主要说说Udp的通讯,相对于Tcp通讯,个人觉得Udp通讯要简单的很多,UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议。
Udp通讯
微卡智享
后台服务端就不说了,还是用的那个Socket的测试工具,我们直接看Unity中怎么实现。
视窗中增加一个UDP的按钮,然后在Network文件夹下增加一个SocketUdp的脚本。
01
添加属性
实例化这样和Tcp的方式是一样的,主要是加入一个UdpClient,一个IPEndPoint(记录服务端IP地址和端口号)
02
初始化连接
Connect参数主要是开启本地UdpClient,通过传入的服务器IP地址和端口号,我们生成IPEndPoint,用于后面发送数据使用的。
03
发送数据
发送数据也比较简单,将传入的字符串转为byte[]后直接用Send即可,最后一个参数就是我们在初始化中已经创建好的服务器的IPEndPoint。
04
接收数据
接收数据我们采用的也是异步处理,不过Udp本身有可能会存在丢包情况,所以本身也不会去考虑分段接收的问题。
因为接收时也要考虑开启监听,所以这里我就写成了协程加异步的方式进行数据的接收处理。基本Udp的核心代码就完成了,下面贴一个这个类
SocketUdp完整代码
代码语言:javascript复制using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;
public class SocketUdp : MonoBehaviour
{
private static SocketUdp _instance;
public static SocketUdp Instance
{
get
{
if (_instance == null)
{
GameObject goRestful = new GameObject("SocketUdp");
_instance = goRestful.AddComponent<SocketUdp>();
}
return _instance;
}
}
private UdpClient _udpClient;
private IPEndPoint _ipendpoint;
/// <summary>
/// 初始化UdpClient
/// </summary>
/// <param name="ipadr"></param>
/// <param name="port"></param>
/// <returns></returns>
public SocketUdp Connect(string ipadr, int port)
{
_ipendpoint = new IPEndPoint(IPAddress.Parse(ipadr), port);
if (_udpClient == null)
{
_udpClient = new UdpClient(0, AddressFamily.InterNetwork);
}
return _instance;
}
public void DisConnect()
{
_udpClient.Close();
_udpClient.Dispose();
_udpClient = null;
}
/// <summary>
/// 发送数据
/// </summary>
/// <param name="msg"></param>
public SocketUdp Send(string msg)
{
byte[] buffer = Encoding.UTF8.GetBytes(msg);
_udpClient.Send(buffer, buffer.Length, _ipendpoint);
return _instance;
}
public void Recv(Action<bool, string> actionResult = null)
{
StartCoroutine(_Recv(actionResult));
}
private IEnumerator _Recv(Action<bool, string> action)
{
while (_udpClient != null)
{
_udpClient.BeginReceive(UdpDataReceived, action);
yield return new WaitForSeconds(0.2f);
}
}
private void UdpDataReceived(IAsyncResult ar)
{
//如果异步已完成。
if (ar.IsCompleted)
{
//结束挂起的异步接收。
byte[] receiveByte = _udpClient.EndReceive(ar, ref _ipendpoint);
//如果收到了数据。
if (receiveByte.Length > 0)
{
//将收到的字节数组转换成字符串。
string str = Encoding.UTF8.GetString(receiveByte);
//调用回调函数
(ar.AsyncState as Action<bool, string>)?.Invoke(true, str);
}
}
}
}
调用方法
实现效果