找回密码
 注册帐号

扫一扫,访问微社区

Like Unity网络编程之UDPClent实现局域网通信

8
回复
4788
查看
[ 复制链接 ]
排名
64951
昨日变化

5

主题

44

帖子

818

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
551
威望
0
注册时间
2020-11-3
在线时间
763 小时
最后登录
2021-2-28
2020-11-6 13:59:13 显示全部楼层 阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
【前言】
UDP通信,是我最开始做一个视频同步的功能开始学习的,随后就开始使用UDPClent做网络传输,我的理解中,UDPClent是system.net网络程序集下的一个关于UDP的网络管理器,底层也是和TCP一样的Socket相关功能封装,多得也不说了,下面我直接放出代码,实现一个简单的发送、接收案例。【基于UDPClent封装的网络管理器类——UDP_Manager】接收是同一端口全部接收,所以收发注意一下端口号,收发的端口号要一致。
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class UDPManager : MonoBehaviour
{
class UDPData
{
private UdpClient udpClient;
public UdpClient UDPClient
{
get { return udpClient; }
}
private readonly IPEndPoint endPoint;
public IPEndPoint EndPoint
{
get { return endPoint; }
}
//构造函数
public UDPData(IPEndPoint endPoint
UdpClient udpClient)
{
this.endPoint = endPoint;
this.udpClient = udpClient;
}
}
public static UDPManager m_instance;
string receiveData = string.Empty;
private Action
<string> ReceiveCallBack = null;
private Thread RecviveThread;
private void Awake()
{
if (m_instance == null)
{
m_instance = this;
}
else
{
Destroy(this);
}
}
private void Start()
{
//开启线程
//ThreadRecvive();
}
private void Update()
{
if (ReceiveCallBack != null &&
!string.IsNullOrEmpty(receiveData))
{
//调用处理函数去数据进行处理
ReceiveCallBack(receiveData);
//使用之后清空接受的数据
receiveData = string.Empty;
}
}
public void SetReceiveCallBack(Action
<string> action)
{
ReceiveCallBack = action;
}
UDPData data;
///

/// 开始线程接收
///
public void ThreadRecvive()
{
//开一个新线程接收UDP发送的数据
RecviveThread = new Thread(() =>
{
//实例化一个IPEndPoint,任意IP和对应端口 端口自行修改
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any5001);
UdpClient udpReceive = new UdpClient(endPoint);
data = new UDPData(endPoint  udpReceive);
//开启异步接收
udpReceive.BeginReceive(CallBackRecvive  data);
})
{
//设置为后台线程
IsBackground = true
};
//开启线程
RecviveThread.Start();
}
///
/// 异步接收回调
///
///
private void CallBackRecvive(IAsyncResult ar)
{
try
{
//将传过来的异步结果转为我们需要解析的类型
UDPData state = ar.AsyncState as UDPData;
IPEndPoint ipEndPoint = state.EndPoint;
//结束异步接受 不结束会导致重复挂起线程卡死
byte[] data = state.UDPClient.EndReceive(ar  ref ipEndPoint);
//解析数据 编码自己调整暂定为默认 依客户端传过来的编码而定
string receiveData = Encoding.Default.GetString(data);
Debug.Log(receiveData);
//数据的解析再Update里执行 Unity中Thread无法调用主线程的方法
//再次开启异步接收数据
state.UDPClient.BeginReceive(CallBackRecvive  state);
}
catch (Exception e)
{
Debug.LogError(e.Message);
throw;
}
}
///
/// 发送UDP信息
///
/// 发送地址
/// 发送端口
/// 需要发送的信息
public void UDPSendMessage(string remoteIP  int remotePort  string message)
{
//将需要发送的内容转为byte数组 编码依接收端为主,自行修改
//byte[] sendbytes = Encoding.GetEncoding(“GB2312”).GetBytes(message);
byte[] sendbytes = Encoding.Default.GetBytes(message);
IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Parse(remoteIP)  remotePort);
UdpClient udpSend = new UdpClient();
//发送数据到对应目标
udpSend.Send(sendbytes  sendbytes.Length  remoteIPEndPoint);
print(“UDPClient发送了=”+message);
//关闭
udpSend.Close();
}
private void OnApplicationQuit()
{
OnDestroy();
}
private void OnDestroy()
{
print(“关闭UDP连接”);
if (RecviveThread != null)
{
RecviveThread.Abort();
}
if (data.UDPClient != null)
{
data.UDPClient.Close();
}
}
}


【测试发送功能——UDP_Send】

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UDPSend : MonoBehaviour
{
UDPManager manager;
// Start is called before the first  update
void Start()
{
//获取到UDPManager 脚本内部自己开启了线程无需再次开启
manager = GetComponent<UDPManager>();
if (manager == null)
{
manager = gameObject.AddComponent<UDPManager>();
}
//设置好解析的方法
}
// Update is called once per
void Update()
{
if (Input.GetMouseButtonDown(1))
{
manager.UDPSendMessage(“192.168.3.113” 5002
”点击了鼠标右键!!”);
//print(“点击了鼠标右键”);
}
}
}


【测试接收功能——UDP_Receive】

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UDPRecvice : MonoBehaviour
{
void Start()
{
//获取到UDPManager 脚本内部自己开启了线程无需再次开启
UDPManager manager = GetComponent<UDPManager>();
if (manager == null)
{
manager = gameObject.AddComponent<UDPManager>();
}
//设置好解析的方法
manager.SetReceiveCallBack(ReceiveUDPMessage);
manager.ThreadRecvive();
}
void ReceiveUDPMessage(string receiveData)
{
//接下来就看自己如何解析了
Debug.Log(receiveData);
}
}






回复

使用道具 举报

7日久生情
4911/5000
排名
2963
昨日变化

33

主题

2792

帖子

4911

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
173503
好友
7
蛮牛币
1835
威望
0
注册时间
2016-10-5
在线时间
1598 小时
最后登录
2021-2-26
2020-12-2 17:18:39 显示全部楼层
工程案例能否提供依稀啊, 里边有各种报错!!
回复 支持 反对

使用道具 举报

排名
64951
昨日变化

5

主题

44

帖子

818

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
551
威望
0
注册时间
2020-11-3
在线时间
763 小时
最后登录
2021-2-28
楼主 2020-12-3 11:41:16 显示全部楼层
kuanyidai 发表于 2020-12-2 17:18
工程案例能否提供依稀啊, 里边有各种报错!!

可能会有“”的字符串里里多了一些\\\\\\,删一下,如果有其它报错,可以私聊我
回复 支持 反对

使用道具 举报

7日久生情
4911/5000
排名
2963
昨日变化

33

主题

2792

帖子

4911

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
173503
好友
7
蛮牛币
1835
威望
0
注册时间
2016-10-5
在线时间
1598 小时
最后登录
2021-2-26
2020-12-3 16:31:31 显示全部楼层
测试成功了。  如果多个命令的话 就需要些多个  UDP_Send?  
回复 支持 反对

使用道具 举报

排名
64951
昨日变化

5

主题

44

帖子

818

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
551
威望
0
注册时间
2020-11-3
在线时间
763 小时
最后登录
2021-2-28
楼主 2020-12-5 22:15:54 显示全部楼层
kuanyidai 发表于 2020-12-3 16:31
测试成功了。  如果多个命令的话 就需要些多个  UDP_Send?

只需要调用UDP管理器类都的UDP_Manager.m_instance.UDPSendMessage方法就可以实现发送,注意下里面的ip和端口即可
回复 支持 反对

使用道具 举报

排名
64951
昨日变化

5

主题

44

帖子

818

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
551
威望
0
注册时间
2020-11-3
在线时间
763 小时
最后登录
2021-2-28
楼主 2020-12-7 19:21:25 显示全部楼层
12-7修改了帖子发布产生的的多余字符串,并测试了代码,如果有问题欢迎留言
回复 支持 反对

使用道具 举报

7日久生情
4911/5000
排名
2963
昨日变化

33

主题

2792

帖子

4911

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
173503
好友
7
蛮牛币
1835
威望
0
注册时间
2016-10-5
在线时间
1598 小时
最后登录
2021-2-26
2020-12-19 20:46:26 显示全部楼层
我想问一下,在发布IPAD端以后,UDP发送是没有问题的,但是熄屏以后再点亮屏幕 UDP通信就会中断? 你有没有好的办法, 我听说有一个解决办法, 按钮点击打开UDP,发送UDP字符串,发送完毕以后再关闭UDP命令,这样就不怕熄屏跟后台操作了?
回复 支持 反对

使用道具 举报

排名
64951
昨日变化

5

主题

44

帖子

818

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
551
威望
0
注册时间
2020-11-3
在线时间
763 小时
最后登录
2021-2-28
楼主 2020-12-20 10:17:16 显示全部楼层
kuanyidai 发表于 2020-12-19 20:46
我想问一下,在发布IPAD端以后,UDP发送是没有问题的,但是熄屏以后再点亮屏幕 UDP通信就会中断? 你有没有 ...

首先要检测一下UDP的连接状态,UDPData.UDPClient.Client.Connected,如果为false应该就是有地方调用了UDPData.UDPClient.Close(); ,看一下是否调用了OnDestroy()方法,主要针对熄屏以后打印一下,看一下它是什么原因导致的中断
回复 支持 反对

使用道具 举报

7日久生情
1865/5000
排名
3720
昨日变化

0

主题

183

帖子

1865

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
246031
好友
1
蛮牛币
1400
威望
0
注册时间
2017-9-26
在线时间
1287 小时
最后登录
2021-2-7
2020-12-21 20:07:03 显示全部楼层
6666666666666666666666
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则