unity UDP传输消息

本文提供了一个Unity中实现UDP通信的示例代码,包括发送端和接收端的实现细节。介绍了如何初始化Socket,发送和接收数据,并处理线程操作。

不和你多BB,直接上代码

接收端

using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

public class UDPServer : MonoBehaviour
{
    public string recvStr;

    Socket socket;
    EndPoint clientEnd;
    IPEndPoint ipEnd;
    string sendStr;
    byte[] recvData = new byte[1024];
    byte[] sendData = new byte[1024];
    int recvLen;
    Thread connectThread;
    //初始化
    void InitSocket()
    {
        ipEnd = new IPEndPoint(IPAddress.Any, 8888);
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        socket.Bind(ipEnd);
        //定义客户端
        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        clientEnd = (EndPoint)sender;
        print("等待连接数据");
        //开启一个线程连接
        connectThread = new Thread(new ThreadStart(SocketReceive));
        connectThread.Start();
    }
    void SocketSend(string sendStr)
    {
        sendData = new byte[1024];
        sendData = Encoding.UTF8.GetBytes(sendStr);
        socket.SendTo(sendData, sendData.Length, SocketFlags.None, clientEnd);
    }
    //服务器接收
    void SocketReceive()
    {
        while (true)
        {
            recvData = new byte[1024];
            recvLen = socket.ReceiveFrom(recvData, ref clientEnd);
          //  print("已连接到: " + clientEnd.ToString()); //打印客户端信息
            recvStr = Encoding.UTF8.GetString(recvData, 0, recvLen);
            Debug.Log(recvStr + "收到的");
            //将接收到的数据经过处理再发送出去
            //  sendStr = "来自服务器: " + recvStr;
            // SocketSend(sendStr);
        }
    }

    //连接关闭
    void SocketQuit()
    {
        //关闭线程
        if (connectThread != null)
        {
            connectThread.Interrupt();
            connectThread.Abort();
        }
        //最后关闭socket
        if (socket != null)
            socket.Close();
        Debug.LogWarning("断开连接");
    }

    // Use this for initialization
    void Start()
    {
        InitSocket(); //在这里初始化server
    }

    void OnApplicationQuit()
    {
        SocketQuit();
    }

}

发送端

using UnityEngine;
using System.Collections;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

public class UDPClient : MonoBehaviour
{
    public string recvStr;
    public string UDPClientIP = "192.168.6.85";//服务端的IP.自己更改;
    string editString = "hello wolrd";
    Socket socket;
    EndPoint serverEnd;
    IPEndPoint ipEnd;

    string sendStr;
    byte[] recvData = new byte[1024];
    byte[] sendData = new byte[1024];
    int recvLen = 0;
    Thread connectThread;

    void Start()
    {
        Read(path);
        UDPClientIP = UDPClientIP.Trim();
        //Debug.LogWarning(UDPClientIP);
        InitSocket(); //在这里初始化
    }
    public void Read(string path)
    {
        StreamReader sr = new StreamReader(path, Encoding.Default);
        string line;

        //print(line);
        for (int i = 0; i < 1; i++)
        {
            line = sr.ReadLine();
            //print(line);
            string[] s = line.Split(':');
            
            switch (i)
            {
                case 0:
                    UDPClientIP = s[1];
                    //  print(UDPClientIP);
                    break;
            }
        }
     }
    void InitSocket()
    {
        //Debug.Log(UDPClientIP);
        ipEnd = new IPEndPoint(IPAddress.Parse(UDPClientIP), 8888);
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        serverEnd = (EndPoint)sender;
        print("等待连接");
        SocketSend("hello");
        print("连接");
        //开启一个线程连接
        connectThread = new Thread(new ThreadStart(SocketReceive));
        connectThread.Start();
    }
    void SocketSend(string sendStr)
    {
        //清空
        sendData = new byte[1024];
        //数据转换
        sendData = Encoding.UTF8.GetBytes(sendStr);
        //发送给指定服务端
        socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
    }

    //服务器接收
    void SocketReceive()
    {
        while (true)
        {

            recvData = new byte[1024];
            try
            {
                recvLen = socket.ReceiveFrom(recvData, ref serverEnd);
            }
            catch (Exception e)
            {
            }

            print("message from: " + serverEnd.ToString());
            if (recvLen > 0)
            {
                recvStr = Encoding.UTF8.GetString(recvData, 0, recvLen);
            }

            print(recvStr);
        }
    }

    //连接关闭
    void SocketQuit()
    {
        //关闭线程
        if (connectThread != null)
        {
            connectThread.Interrupt();
            connectThread.Abort();
        }
        //最后关闭socket
        if (socket != null)
            socket.Close();
    }
    void OnApplicationQuit()
    {
        SocketQuit();
    }

    void Update()
    {

    }
    private string path;
    private void Awake()
    {
        path = "C:\\ip.txt";
    }

    public void ButtonSend(string a)
    {
        SocketSend(a);
    }

    public void ButtonDoSomething()
    {
        ButtonSend("DoSomething");
     
    }
   

}

我的ip是外部可更改的,不需要的自己注释掉

<think>根据用户的问题,用户希望了解Unity中简单的UDP传输实现方法。结合站内引用内容,可以总结出以下关键点: 1. UDP协议特点:无连接、高效但不可靠(引用[4]) 2. 实现步骤:创建Socket、绑定端口、发送/接收数据(引用[3][5]) 3. 代码示例:引用[3]提供了Unity客户端的UDP发送示例,引用[5]展示了服务器端的多线程处理 实现步骤: 1. 创建UDP客户端: - 使用`Socket`类,指定`ProtocolType.Udp` - 设置目标终结点(IP和端口) - 将数据转换为字节数组发送 2. 创建UDP服务端: - 创建Socket并绑定本地终结点 - 开启线程接收数据(异步处理) 简单实现方案(双向通信): - 客户端:发送消息并接收响应 - 服务端:接收消息并回复 注意:Unity中需要在主线程更新UI,因此接收数据后需使用委托或Unity主线程调度器更新界面。 参考代码结构: 1. UDP客户端脚本(附加到GameObject): ```csharp using UnityEngine; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; public class UDPClient : MonoBehaviour { public string serverIP = "127.0.0.1"; public int serverPort = 7777; private Socket clientSocket; private EndPoint serverEndPoint; private Thread receiveThread; private bool isRunning = true; void Start() { // 初始化Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); serverEndPoint = new IPEndPoint(IPAddress.Parse(serverIP), serverPort); // 启动接收线程 receiveThread = new Thread(ReceiveData); receiveThread.Start(); // 示例:发送测试消息 SendMessage("Hello UDP Server!"); } void SendMessage(string message) { byte[] data = Encoding.UTF8.GetBytes(message); clientSocket.SendTo(data, serverEndPoint); } void ReceiveData() { while (isRunning) { byte[] buffer = new byte[1024]; int received = clientSocket.ReceiveFrom(buffer, ref serverEndPoint); string receivedMsg = Encoding.UTF8.GetString(buffer, 0, received); // 注意:Unity中需通过主线程更新UI Debug.Log("Received: " + receivedMsg); } } void OnApplicationQuit() { isRunning = false; if (receiveThread != null && receiveThread.IsAlive) receiveThread.Join(); clientSocket.Close(); } } ``` 2. UDP服务端(独立控制台应用或Unity中附加脚本): ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; class UDPServer { static Socket serverSocket; static void Main() { serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); serverSocket.Bind(new IPEndPoint(IPAddress.Any, 7777)); Console.WriteLine("Server started"); Thread receiveThread = new Thread(ReceiveMessages); receiveThread.Start(); } static void ReceiveMessages() { EndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0); while (true) { byte[] buffer = new byte[1024]; int received = serverSocket.ReceiveFrom(buffer, ref clientEndPoint); string message = Encoding.UTF8.GetString(buffer, 0, received); Console.WriteLine($"Received: {message} from {clientEndPoint}"); // 回复确认 byte[] response = Encoding.UTF8.GetBytes($"Echo: {message}"); serverSocket.SendTo(response, clientEndPoint); } } } ``` 关键注意事项: 1. 线程安全:Unity中接收数据需通过`MainThreadDispatcher`或`[ExecuteInEditMode]`更新游戏对象 2. 端口绑定:确保端口未被占用 3. 数据编码:统一使用UTF-8编码避免乱码 4. 资源释放:应用退出时关闭Socket和线程 性能优化建议: - 大文件传输需分片处理 - 高频小数据包适用UDP(如实时视频) - 添加简单校验提高可靠性(如引用[2]提到的可靠UDP机制) 相关问题: 1. 如何处理UnityUDP接收数据的线程安全问题? 2. UDP传输视频数据需要注意哪些问题? 3. 如何实现基本的可靠UDP传输机制? </think> 以下是Unity中实现简单UDP传输的详细指南,结合站内引用内容整理: ### UDP传输基础原理 UDP(用户数据报协议)是一种无连接的传输协议,特点包括: - ✅ **优点**:传输效率高、延迟低、无需建立连接(引用[4]) - ⚠️ **缺点**:不保证数据可靠性,可能出现丢失、乱序、重复(引用[4]) - 📌 **适用场景**:实时视频流、游戏状态同步等对延迟敏感的场景(引用[1][2]) --- ### 简单UDP实现步骤(双向通信) #### 1. UDP客户端实现(Unity端) ```csharp using UnityEngine; using System.Net; using System.Net.Sockets; using System.Text; public class UDPClient : MonoBehaviour { public string serverIP = "127.0.0.1"; // 服务器IP public int serverPort = 7777; // 服务器端口 public int clientPort = 8001; // 本地端口 private Socket clientSocket; private EndPoint serverEndPoint; void Start() { // 创建UDP Socket clientSocket = new Socket( AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp ); // 绑定本地端口(可选) clientSocket.Bind(new IPEndPoint(IPAddress.Any, clientPort)); // 设置服务器地址 serverEndPoint = new IPEndPoint(IPAddress.Parse(serverIP), serverPort); // 发送测试消息 SendMessage("Hello UDP Server!"); } // 发送消息方法 public void SendMessage(string message) { byte[] data = Encoding.UTF8.GetBytes(message); clientSocket.SendTo(data, serverEndPoint); Debug.Log($"Sent: {message}"); } // 接收消息方法(需在Update中调用) void Update() { if (clientSocket.Available > 0) { byte[] buffer = new byte[1024]; int received = clientSocket.Receive(buffer); string response = Encoding.UTF8.GetString(buffer, 0, received); Debug.Log($"Received: {response}"); } } void OnDestroy() { clientSocket?.Close(); } } ``` #### 2. UDP服务端实现(C#控制台应用) ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; class UDPServer { static void Main() { // 创建Socket并绑定端口 Socket serverSocket = new Socket( AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp ); serverSocket.Bind(new IPEndPoint(IPAddress.Any, 7777)); Console.WriteLine("Server started..."); // 接收循环 while (true) { byte[] buffer = new byte[1024]; EndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0); // 接收数据 int received = serverSocket.ReceiveFrom(buffer, ref clientEndPoint); string message = Encoding.UTF8.GetString(buffer, 0, received); Console.WriteLine($"Received: {message} from {clientEndPoint}"); // 回复客户端 byte[] response = Encoding.UTF8.GetBytes($"Echo: {message}"); serverSocket.SendTo(response, clientEndPoint); } } } ``` --- ### 关键注意事项 1. **端口绑定**: - 服务端必须绑定固定端口(如`Bind(7777)`) - 客户端可选择绑定端口或使用随机端口(引用[5]) 2. **线程处理**: - 服务端建议使用独立线程接收数据(引用[5]): ```csharp Thread receiveThread = new Thread(ReceiveMessages); receiveThread.Start(); ``` 3. **数据编码**: - 统一使用`Encoding.UTF8`进行字节转换(引用[3]) 4. **视频传输优化**: - 大视频数据需分片传输 - 添加帧编号解决乱序问题(引用[1]) - 使用压缩算法(如H.264)减少数据量 5. **可靠性增强**: - 实现ACK确认机制 - 添加数据包重传逻辑(引用[2]) --- ### 典型问题解决方案 **画面闪烁问题**(引用[1]): 1. 使用双缓冲机制:前台显示完整帧时,后台接收下一帧 2. 添加时间戳校验:丢弃延迟过高的帧 3. 实现帧插值:在网络波动时自动补帧 **数据丢失处理**(引用[2][4]): ```csharp // 简易重传机制示例 public void SendWithRetry(string message, int maxRetries = 3) { for(int i=0; i<maxRetries; i++) { SendMessage(message); if (WaitForAck(500)) break; // 等待500ms确认 } } ``` --- ### 相关问题 1. 如何解决UDP传输中的画面闪烁问题?[^1] 2. UDP传输视频数据时如何优化性能?[^1][^2] 3. 怎样在UDP基础上实现可靠传输机制? 4. Unity中如何处理多客户端UDP通信?[^5] 5. 如何验证UDP数据包的完整性?[^4] [^1]: 引用自Unity传输摄像头视频实践 [^2]: 可靠UDP实现技术 : UDP协议特性分析 [^5]: UDP服务器多线程处理
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值