Unity简单的UDP通信


UDP通信的优势

UDP通信的优势在于不要求对方强制在线,没有因为网络连接不顺畅或连接失败导致的卡顿问题;缺点也是因为不能判断对方是否在线,导致整个连接不可靠,需要通过自定义代码来进行反馈。

UDP的使用

下列代码就是一个简单的UDP通信基类,继承此类后,需调用 InitSocket 方法初始化才可使用,这里没有直接初始化的原因是有可能需要修改端口号或者在其他设置之后才能进行初始化操作,所以初始化操作放到子类进行。
初始化完成后,就可以通过 SendMessage 发送消息,通过 DequeueData 获取收到的消息,通过 DequeueDataCount 查看未处理消息数量,从而实现一个简单的UDP通信。


using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using UnityEngine;

public class UDPBase : MonoBehaviour
{
    
    

    protected int localPort = 54321;      //本地端口
    protected int sendPort = 12345;       //接收端的端口

    private Socket serverSocket;        //Socket对象用于创建本地UDP通道
    private static UdpClient client;    //UdpClient对象,用于与接收端通信
    private EndPoint clientEndPoint;    //用于承载发送消息的服务器的EndPoint信息
    private byte[] ReceiveData = new byte[1024];    //创建数据缓冲区,用于接收发送来的数据
    private Queue<byte[]> dataQueue = new Queue<byte[]>();  //接收数据队列,存入原始数据,特性:先入先出


    /// <summary>
    /// 初始化Socket
    /// </summary>
    protected void InitSocket()
    {
    
    
        //实例化UDP服务器的Socket通道
        serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        //Socket绑定IP和端口
        serverSocket.Bind(new IPEndPoint(IPAddress.Any, localPort));
        clientEndPoint = (EndPoint)new IPEndPoint(IPAddress.Any, 0);
        //开始异步接收数据
        serverSocket.BeginReceiveFrom(ReceiveData, 0, ReceiveData.Length, 
            SocketFlags.None, ref clientEndPoint, new AsyncCallback(ReceiveMessageToQueue), clientEndPoint);

        client = new UdpClient();

    }

    /// <summary>
    /// 接收消息并存放 
    /// </summary>
    /// <param name="iar"></param>
    private void ReceiveMessageToQueue(IAsyncResult iar)
    {
    
    
        int receiveDataLength = serverSocket.EndReceiveFrom(iar, ref clientEndPoint);

        //继续监听
        serverSocket.BeginReceiveFrom(ReceiveData, 0, ReceiveData.Length,
            SocketFlags.None, ref clientEndPoint, new AsyncCallback(ReceiveMessageToQueue), clientEndPoint);

        if (receiveDataLength > 0)
        {
    
    
            byte[] data = new byte[receiveDataLength];
            Buffer.BlockCopy(ReceiveData,0, data,0, receiveDataLength);
            dataQueue.Enqueue(data);
        }

    }

    /// <summary>
    /// 从队列中取出数据
    /// </summary>
    /// <returns></returns>
    protected byte[] DequeueData()
    {
    
    
       return dataQueue.Dequeue();
    }

    protected int DequeueDataCount
    {
    
    
        get {
    
     return dataQueue.Count; }
    }



    /// <summary>
    /// 发送消息
    /// </summary>
    /// <param name="ipEndPoint"></param>
    /// <param name="sendData"></param>
    protected void SendMessage(IPEndPoint ipEndPoint, byte[] sendData)
    {
    
    
        client.Send(sendData, sendData.Length, ipEndPoint);
    }

    /// <summary>
    /// 发送消息
    /// </summary>
    /// <param name="ipEndPoint"></param>
    /// <param name="sendStr"></param>
    protected void SendMessage(IPEndPoint ipEndPoint, string sendStr)
    {
    
    
        byte[] sendData = System.Text.Encoding.UTF8.GetBytes(sendStr);
        SendMessage(ipEndPoint, sendData);
    }


    /// <summary>
    /// 关闭Socket
    /// </summary>
    public void SocketQuit()
    {
    
    
        if (serverSocket != null)
        {
    
    
            serverSocket.Close();
        }
    }


    /// <summary>
    /// 当关闭此对象时关闭Socket
    /// </summary>
    private void OnDestroy()
    {
    
    
        SocketQuit();
    }


}

猜你喜欢

转载自blog.csdn.net/qq_27050589/article/details/128411961