之前一篇文章已经完成了TXT中IP地址的读取,接下来要实现在Unity中进行UDP通信的功能
ShowcasePanel 上面挂载的脚本 _UPDManager,主要负责和UE4进行UDP通信
以下是 UPDManager.cs 的代码
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
//负责UDP网络连接及消息收发
//在按钮作出一个操作的时候,必须收到来自UE4的反馈,才可以改变用户界面
public class _UPDManager : MonoBehaviour
{
//自身的 IP地址 及 端口号
private IPEndPoint server_Address;
//Socket服务实例
private Socket UDPServer;
//接收到的数据
private byte[] data_Receive = new byte[1024];
//要发送的数据
private byte[] data_Send = new byte[1024];
//用于接收数据的线程
private Thread receiveThread;
//接收数据的来源(任何IP,任何端口)
EndPoint receiver_EndPoint = new IPEndPoint(IPAddress.Any, 0);
void Awake()
{
InitSocket();
}
void OnApplicationQuit()
{
SocketQuit();
}
//初始化Socket连接
private void InitSocket()
{
//设置IP地址和端口号,用户监听消息
server_Address = new IPEndPoint(IPAddress.Parse(GetCurrentIP()), 2333);
//初始化Socket
UDPServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
UDPServer.Bind(server_Address);
//启动接收数据的线程
receiveThread = new Thread(Socket_Receive);
receiveThread.Start();
}
//接收来自UE4的消息
private void Socket_Receive()
{
while (true)
{
//清空之前收到的数据
data_Receive = new byte[1024];
//接收数据
//ReceiveFrom 方法的第二个参数会保存消息来源的IP地址和端口号
//ReceiveFrom 在收到消息之前会一直等待
int dataLength = UDPServer.ReceiveFrom(data_Receive, ref receiver_EndPoint);
//判断 接收到的数据长度大于0 否则不做任何操作
if (dataLength > 0)
{
//将接收到的数据转换为字符串
string msg = Encoding.UTF8.GetString(data_Receive, 0, dataLength);
Debug.Log(
"消息来源IP:" + (receiver_EndPoint as IPEndPoint).Address.ToString() +
" 端口号为:" + (receiver_EndPoint as IPEndPoint).Port.ToString() +
" 消息内容为:" + msg
);
}
}
}
//向UE4发送消息
public void Socket_Send(string _msg)
{
data_Send = Encoding.UTF8.GetBytes(_msg);
//将消息发送给指定IP地址和端口
IPEndPoint IP_Address = new IPEndPoint(IPAddress.Parse(_Global.IPAddress), 7890);
UDPServer.SendTo(data_Send, IP_Address);
}
//终止线程 并 关闭socket,防止再次启动APP的时候端口被占用
private void SocketQuit()
{
//终止线程
if (receiveThread != null)
{
receiveThread.Interrupt();
receiveThread.Abort();
}
//关闭socket
if (UDPServer != null)
UDPServer.Close();
}
//获取本机的IP地址
private string GetCurrentIP()
{
string name = Dns.GetHostName();
IPAddress[] ipadrlist = Dns.GetHostAddresses(name);
foreach (IPAddress ipa in ipadrlist)
{
if (ipa.AddressFamily == AddressFamily.InterNetwork)
{
return ipa.ToString();
}
}
return null;
}
}
Socket_Send 方法可以用一个UGUI按钮调用,参数为一个字符串,返回的字符串接收后也可以放到另外一个类中处理,这里先写最基本的代码,之后还要再做改动
大家在写UDP的时候,推荐新建一个CMD的工程也写一个UDP接收与发送的功能,这样可以实时测试Unity中写的是否正确,发送和接收功能是否能正常运行,免得在连接UE4之后有了问题不知道从哪下手
下面给出我写的一个控制台UDP程序,方便大家使用和调试,这里注释就不写那么全了,基本和unity中的UDP一个意思
using System;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace UDPDemo_CMDServer
{
class Program
{
static Socket UDPServer;
static void Main(string[] args)
{
//声明UDP协议
UDPServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//绑定 IP 和 端口号
IPEndPoint IP_Address = new IPEndPoint(IPAddress.Parse("10.150.0.26"), 7890);
UDPServer.Bind(IP_Address);
new Thread(ReceiveMsg) { IsBackground = true }.Start();
Console.ReadKey();
}
static void ReceiveMsg()
{
while (true)
{
//接收数据
//表示从任何IP和任何端口接收数据
EndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
//存放接收到的数据
byte[] data = new byte[1024];
//ReceiveFrom 的第二个参数为消息来源的IP地址和端口号
int dateLength = UDPServer.ReceiveFrom(data, ref RemoteEndPoint);
string msg = Encoding.UTF8.GetString(data, 0, dateLength);
Console.WriteLine("IP地址为:" + (RemoteEndPoint as IPEndPoint).Address.ToString() + " 端口号为:" + (RemoteEndPoint as IPEndPoint).Port.ToString() + " " + msg);
string _msg = "woshifanhuidexiaoxi";
byte[] data2 = new byte[1024];
data2 = Encoding.UTF8.GetBytes(_msg);
IPEndPoint IP_Address2 = new IPEndPoint((RemoteEndPoint as IPEndPoint).Address, (RemoteEndPoint as IPEndPoint).Port);
UDPServer.SendTo(data2, IP_Address2);
Console.WriteLine("消息已经发出 " + _msg);
}
}
}
}