馬上注冊,結交更多好友,享用更多功能,讓你輕松玩轉社區。
您需要 登錄 才可以下載或查看,沒有帳號?注冊帳號
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);
}
}
|