Unity-UDP-客户端/服务器通信功能

UDP介绍

这里简单实现客户端和服务器,复杂的实现需要和前几篇文章的TCP一样,管理多个链接过来的客户端,这里只有一个。需要自己封装类似listener来管理多个链接过来的设备,每次都缓存ReceiveAsync收到消息的中的RemoteEndPoint地址端口,统一管理发送接收消息。

https://zhidao.baidu.com/question/2203388361996423948.html
是这样的,UDP有一个保活时间,在P2P中,叫洞,如果这个洞没有一段时间内有数据通过,会关闭。
这个时间和特性是和你的NAT设备决定。

这也是为什么UDP不像TCP一样有Listener。

通信实现

namespace Server.Net
{
    internal class UDPServer
    {
        UdpClient udpClient;
        public void Start()
        {
            try
            {
                udpClient = new UdpClient(8899);
                Console.WriteLine("UDP Server 启动成功 8899");
                Receive();
            }
            catch (Exception e)
            {
                Console.WriteLine("UDP Server Error:" + e.Message);
            }
        }

        IPEndPoint remote;//临时用于保存连接的udp客户端
        private async void Receive()
        {
            while (udpClient != null)
            {
                try
                {
                    var result = await udpClient.ReceiveAsync();
                    remote = result.RemoteEndPoint;
                    var text = Encoding.UTF8.GetString(result.Buffer);
                    Console.WriteLine($"收到客户端发过来的数据:{text}");
                }
                catch (Exception e)
                {
                    Console.WriteLine("接收异常:" + e.Message);
                    udpClient.Close();
                    udpClient = null;
                }
            }
        }

        public async void Send(byte[] data)
        {
            int length = await udpClient.SendAsync(data, data.Length, remote);
            Console.WriteLine($"UDP Send:{length}");
        }
    }
}
#define UDP//在这里修改Server类型
    
namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
#if TCP
            Console.OutputEncoding = Encoding.UTF8;
            TCPServer tcpServer = new TCPServer();
            tcpServer.Start();
            while(true)
            {
                var str = Console.ReadLine();//监听用户输入,不写这句话运行测试会立刻跳出
            }
#elif UDP
            UDPServer server = new UDPServer();
            server.Start();
            while (true)
            {
                string text = Console.ReadLine();
                server.Send(Encoding.UTF8.GetBytes(text));
            }
#endif
        }
    }
}

Unity编写脚本Clinet_UDP,创建新Scene,随便找物体挂上去

public class Client_UDP : MonoBehaviour
{
    private UdpClient udpClient;
    // Start is called before the first frame update
    void Start()
    {
        udpClient = new UdpClient();
        Receive();
    }

    private async void Receive()
    {
        while (udpClient != null)
        {
            try
            {
                UdpReceiveResult result = await udpClient.ReceiveAsync();
                Debug.Log(Encoding.UTF8.GetString(result.Buffer));
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
                udpClient.Close();
                udpClient = null;
            }
        }
    }

    public async void Send(byte[] data)
    {
        if (udpClient != null)
        {
            try
            {
                int length = await udpClient.SendAsync(data, data.Length, "127.0.0.1", 8899);
                if (data.Length == length)
                {
                    Debug.Log("完整的发送");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                udpClient.Close();
            }
        }
    }
    
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            Send(Encoding.UTF8.GetBytes("UDP Send Test"));
        }
    }
}

运行测试

猜你喜欢

转载自blog.csdn.net/weixin_42264818/article/details/128839977