Unity3D网络通讯(五)--Socket通讯之Udp通讯
时间:2022-07-25
本文章向大家介绍Unity3D网络通讯(五)--Socket通讯之Udp通讯,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前言
上一篇《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完整代码
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);
}
}
}
}
调用方法
实现效果
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- HTML5新增全局属性
- 漫画:如何找到链表的倒数第n个结点?
- 微信小程序使用npm
- Flink SQL 自定义 format
- 在页面离开前提醒你的beforeunload事件
- 忘记MySQL密码怎么办?一招教你搞定!
- 夺冠 or 姜子牙?ChatBot帮你搞定:基于话题引导的对话推荐系统
- 数据处理思想和程序架构: 使用Mbedtls包中的SSL,和服务器进行网络加密通信
- 密度聚类DBSCAN、HDBSCAN
- 用Python对两个数据集中的图像进行水平拼接
- 电脑设置了静态IP,但还是分配了动态IP169.254..,且不能上网
- 转HDevWindowStack详解
- 抽象工厂模式
- webpack实战——打包优化【上】
- c# 中for和foreach循环的区别