当前位置: 首页 > article >正文

用Unity实现UDP客户端同步通信

制作UDPNetMgr网络管理模块

这段代码定义了一个名为UDPNetMgr的 Unity 脚本类,用于管理 UDP 网络通信,它作为单例存在,在Awake方法中创建收发消息的线程,Update方法处理接收到的消息;StartClient方法启动客户端连接,ReceiveMsgSendMsg方法分别用于接收和发送消息,Send方法将消息加入发送队列,Close方法关闭套接字并发送退出消息,同时在脚本销毁时自动调用关闭操作

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;public class UDPNetMgr : MonoBehaviour
{ private static UDPNetMgr instance;public static UDPNetMgr Instance => instance;private EndPoint serverIpPoint;public Socket socket;private bool IsClose=true;public byte[] cacheBytes = new byte[512];//创建两个队列来收消息和发消息public Queue<BaseMsg> sendMsgQueue = new Queue<BaseMsg>();public Queue<BaseMsg> receiveMsgQueue = new Queue<BaseMsg>();void Awake(){instance = this;DontDestroyOnLoad(this.gameObject);//创建两个线程来执行收发消息ThreadPool.QueueUserWorkItem(ReceiveMsg);ThreadPool.QueueUserWorkItem(SendMsg);}// Update is called once per framevoid Update(){if(receiveMsgQueue .Count >0){BaseMsg basemsg = receiveMsgQueue.Dequeue();switch (basemsg ){case PlayerMsg msg:print(msg.playerID);print(msg.playerData .atk);print(msg.playerData .lev);print(msg.playerData .name);break;}}}//启动客户端Socket的方法public void StartClient(string ip,int port){if (!IsClose)return;//记录远端服务器的Ip和端口号serverIpPoint = new IPEndPoint(IPAddress.Parse(ip), port);IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8081);try{socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);socket.Bind(ipPoint);IsClose = false;print("客户端网络启动");}catch (System.Exception e){print("启动客户端Socket失败" + e.Message);}}//接收消息的方法public void ReceiveMsg(object obj){EndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 0);int msgID;int nowIndex;int msgLength;while (socket!=null&&!IsClose){try{socket.ReceiveFrom(cacheBytes, ref ipEndPoint);//为了避免非服务器发来的骚扰消息if (!ipEndPoint.Equals(serverIpPoint))continue;//如果不是服务器发来的消息,就不处理了//处理服务器发来的消息nowIndex = 0;//解析IDmsgID = BitConverter.ToInt32(cacheBytes, nowIndex);nowIndex += 4;//解析消息长度msgLength = BitConverter.ToInt32(cacheBytes, nowIndex);nowIndex += 4;//解析消息体BaseMsg msg = null;switch (msgID){case 1001:msg = new PlayerMsg();//反序列化消息体msg.Reading(cacheBytes, nowIndex);break;}if (msg != null)receiveMsgQueue.Enqueue(msg);}catch (SocketException s){print("接收消息出问题" + s.SocketErrorCode + s.Message);}catch (System.Exception e){print("接收消息出问题(非网络问题)" + e.Message);}}}//发送消息的方法public void SendMsg(object obj){while (socket!=null&&!IsClose){if(sendMsgQueue .Count >0){try{socket.SendTo(sendMsgQueue.Dequeue().Writing(), serverIpPoint);}catch (SocketException e){print("发送消息失败" + e.SocketErrorCode + e.Message);}}}}public void Send(BaseMsg msg){sendMsgQueue.Enqueue(msg);}//关闭socketpublic void Close(){if(socket!=null){IsClose = true;quitMsg quitMsg = new quitMsg();//发送一个退出消息给服务器,让他移除记录socket.SendTo(quitMsg.Writing(), serverIpPoint);socket.Shutdown(SocketShutdown.Both);socket.Close();}}private void OnDestroy(){Close();}
}

启动UDP客户端

MainUDP类继承自MonoBehaviour,是一个 Unity 脚本。它的主要功能是在游戏开始时确保UDPNetMgr单例实例存在,然后启动 UDP 客户端并连接到指定的服务器地址和端口。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MainUDP : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){if(UDPNetMgr .Instance ==null){GameObject obj = new GameObject("UdpNet");obj.AddComponent<UDPNetMgr>();}UDPNetMgr.Instance.StartClient(("127.0.0.1"), 8080);}// Update is called once per framevoid Update(){}
}

让客户端给服务器发消息

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Lesson15 : MonoBehaviour
{public Button btn;// Start is called before the first frame updatevoid Start(){btn.onClick.AddListener(() =>{PlayerMsg playerMsg = new PlayerMsg();playerMsg.playerID = 1;playerMsg.playerData.atk = 888;playerMsg.playerData.lev = 999;playerMsg.playerData.name = "DamnF客户端发来的消息";UDPNetMgr.Instance.Send(playerMsg);});}// Update is called once per framevoid Update(){}
}

实现客户端和服务器同步通信

运行服务器,启动客户端,使客户端和服务器实现UDP同步通信

相关文章:

用Unity实现UDP客户端同步通信

制作UDPNetMgr网络管理模块 这段代码定义了一个名为UDPNetMgr的 Unity 脚本类&#xff0c;用于管理 UDP 网络通信&#xff0c;它作为单例存在&#xff0c;在Awake方法中创建收发消息的线程&#xff0c;Update方法处理接收到的消息&#xff1b;StartClient方法启动客户端连接&a…...

pandoc安装及基础使用

pandoc安装 访问pandoc tags,切换至想要安装的版本&#xff0c;本次安装3.6.4 下载windows版本 下载texlive镜像&#xff0c;将文件转换成pdf需要用到 点开后会进入最近的镜像网站 下载完成后解压iso文件&#xff0c;以管理员身份运行install-tl-windows.bat&#xff…...

C++:无序关联容器

遇到的问题&#xff0c;都有解决方案&#xff0c;希望我的博客能为您提供一点帮助。 一、无序关联容器概述 无序关联容器&#xff08;如 unordered_set、unordered_map、unordered_multiset、unordered_multimap&#xff09;基于 ​哈希表&#xff08;Hash Table&#xff09;​…...

3.27学习总结 算法题

自己用c语言做的&#xff0c;不尽如意 后面看了题解&#xff0c;用的是c&#xff0c;其中string 变量和字符串拼接感觉比c方便好多&#xff0c;可以用更少的代码实现更好的效果&#xff0c;打算之后去学习c&#xff0c;用c写算法。 递归&#xff0c;不断输入字符&#xff0c;…...

案例分享|树莓派媒体播放器,重构商场广告的“黄金三秒”

研究显示&#xff0c;与传统户外广告相比&#xff0c;数字户外广告在消费者心中的记忆率提高了17%&#xff0c;而动态户外广告更是能提升16%的销售业绩&#xff0c;整体广告效率提升了17%。这一显著优势&#xff0c;使得越来越多资源和技术流入数字广告行业。 户外裸眼3D广告 无…...

Redisson - 分布式锁和同步器

文章目录 锁&#xff08;Lock&#xff09;公平锁&#xff08;Fair Lock&#xff09;联锁&#xff08;MultiLock&#xff09;红锁&#xff08;RedLock&#xff09; 【已废弃】读写锁&#xff08;ReadWriteLock&#xff09;信号量&#xff08;Semaphore&#xff09;可过期许可信号…...

Zustand 状态管理:从入门到实践

Zustand 状态管理&#xff1a;从入门到实践 Zustand 是一个轻量、快速且灵活的 React 状态管理库。它基于 Hooks API&#xff0c;提供了简洁的接口来创建和使用状态&#xff0c;同时易于扩展和优化。本文将通过一个 TODO 应用实例带你快速入门 Zustand&#xff0c;并探讨其核心…...

[RITSEC CTF 2025] Crypto

这个忘打了&#xff0c;难度不小。 Alien Encryption 101 一个很小的RSA&#xff0c;略 Cuwves 2 Electric Boogaloo 已知p,在p^2下的两个椭圆曲线的j不变量&#xff0c;直接用函数 Mothership AES_CBC加密给出密文和IV&#xff0c;通过调整IV来修改明文 import base64 …...

算法250327题目

1114: 4006 AB问题 题目描述 给定两个整数A和B&#xff0c;其表示形式是&#xff1a;从个位开始&#xff0c;每三位数用逗号,隔开。 现在请计算AB的结果&#xff0c;并以正常形式输出。 输入 输入包含多组数据&#xff0c;每组数据占一行&#xff0c;由两个整数A和B组成&am…...

PGP实现简单加密教程

模拟情景&#xff1a; 假设001和002两位同学的电脑上都安装了PGP&#xff0c;现在两人需要进行加密通讯。 一、创建密钥 1.新建密钥&#xff0c;输入名称和邮箱&#xff0c;输入8位口令&#xff0c;根据指示完成。 2.将其添加到主密钥&#xff0c;鼠标右击出现选项。 这里出…...

7.8 窗体间传递数据

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的 当项目中有多个窗体时&#xff08;在本节中为两个窗体&#xff1a;Form1和Form2&#xff09;&#xff0c;窗体间传递数据有以下几种方…...

一文了解 MCP Server:AI 工具与外部世界的桥梁

引言 随着大语言模型&#xff08;LLM&#xff09;的普及与 AI Agent 的爆发&#xff0c;Anthropic 于 2024 年底提出并开源的 Model Context Protocol&#xff08;MCP&#xff0c;模型上下文协议&#xff09;成为构建智能体系统的关键基石之一。本文将结合最新的实战经验&#…...

【redis】集群 数据分片算法:哈希求余、一致性哈希、哈希槽分区算法

文章目录 什么是集群数据分片算法哈希求余分片搬运 一致性哈希扩容 哈希槽分区算法扩容相关问题 什么是集群 广义的集群&#xff0c;只要你是多个机器&#xff0c;构成了分布式系统&#xff0c;都可以称为是一个“集群” 前面的“主从结构”和“哨兵模式”可以称为是“广义的…...

基于Springboot的网上订餐系统 【源码】+【PPT】+【开题报告】+【论文】

网上订餐系统是一个基于Java语言和Spring Boot框架开发的Web应用&#xff0c;旨在为用户和管理员提供一个便捷的订餐平台。该系统通过简化餐饮订购和管理流程&#xff0c;为用户提供快速、高效的在线订餐体验&#xff0c;同时也为管理员提供完善的后台管理功能&#xff0c;帮助…...

Redis常见面试问题汇总

Redis 面试笔记整理 一、Redis 基础知识1. Redis 概述Redis 是什么&#xff1f;主要特点有哪些&#xff1f;Redis 和 Memcached 的区别是什么&#xff1f;Redis 是单线程还是多线程&#xff1f;为什么单线程还能高效&#xff1f;Redis 6.0 之后的多线程模型是怎样的&#xff1f…...

【redis】集群 如何搭建集群详解

文章目录 集群搭建1. 创建目录和配置2. 编写 docker-compose.yml完整配置文件 3. 启动容器4. 构建集群超时 集群搭建 基于 docker 在我们云服务器上搭建出一个 redis 集群出来 当前节点&#xff0c;主要是因为我们只有一个云服务器&#xff0c;搞分布式系统&#xff0c;就比较…...

NLP高频面试题(二十)——flash attention原理

FlashAttention是一种针对Transformer模型中自注意力机制的优化算法&#xff0c;旨在提高计算效率并降低内存占用&#xff0c;特别适用于处理长序列任务。 在Transformer架构中&#xff0c;自注意力机制的计算复杂度和内存需求随着序列长度的平方增长。这意味着当处理较长序列时…...

飞牛NAS本地部署小雅Alist结合内网穿透实现跨地域远程在线访问观影

文章目录 前言1. VMware安装飞牛云&#xff08;fnOS&#xff09;1.1 打开VMware创建虚拟机1.3 初始化系统 2. 飞牛云搭建小雅Alist3. 公网远程访问小雅Alist3.1 安装Cpolar内网穿透3.2 创建远程连接公网地址 4. 固定Alist小雅公网地址 前言 嘿&#xff0c;小伙伴们&#xff0c…...

Episode, time step, batch, epoch

1. Episode&#xff08;回合&#xff09; 回合&#xff08;episode&#xff09;表示智能体从开始执行任务到完成任务&#xff08;例如成功到达目标或触发失败条件&#xff09;的全过程。 例如&#xff0c;如果我们训练一个四足机器人走到一个目标点&#xff0c;一个回合就是从…...

Linux版本控制器Git【Ubuntu系统】

文章目录 **前言**一、版本控制器二、Git 简史三、安装 Git四、 在 Gitee/Github 创建项目五、三板斧1、git add 命令2、git commit 命令3、git push 命令 六、其他1、git pull 命令2、git log 命令3、git reflog 命令4、git stash 命令 七、.ignore 文件1、为什么使用 .gitign…...

browser-use 库网页元素点击测试工具

目录 代码代码解释输出结果 代码 import asyncio import jsonfrom browser_use.browser.browser import Browser, BrowserConfig from browser_use.dom.views import DOMBaseNode, DOMElementNode, DOMTextNode from browser_use.utils import time_execution_syncclass Eleme…...

Vue 中使用 ECharts

在 Vue 中使用 ECharts 主要分为以下步骤&#xff0c;结合代码示例详细说明&#xff1a; 1. 安装 ECharts 通过 npm 或 yarn 安装 ECharts&#xff1a; npm install echarts --save # 或 yarn add echarts2. 基础使用&#xff08;完整引入&#xff09; 在 Vue 组件中使用 &…...

Spring AI + DeepSeek 构建大模型应用 Demo

Spring AI + DeepSeek 构建大模型应用 Demo 下面我将展示如何使用 Spring AI 框架结合 DeepSeek 的大模型能力构建一个简单的 AI 应用。 1. 环境准备 首先确保你已安装: JDK 17+Maven 3.6+Spring Boot 3.2+2. 创建 Spring Boot 项目 使用 Spring Initializr 创建项目,添加…...

解决GitLab无法拉取项目

1、验证 SSH 密钥是否已生成 ls ~/.ssh/ 如果看到类似 id_rsa 和 id_rsa.pub 的文件&#xff0c;则说明已存在 SSH 密钥。 避免麻烦&#xff0c;铲掉重来最方便。 如果没有&#xff0c;请生成新的 SSH 密钥&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexam…...

POSIX 线程取消与资源清理完全指南

POSIX 线程取消与资源清理完全指南 引言&#xff1a;为什么需要线程取消机制&#xff1f; 在多线程编程中&#xff0c;优雅地终止线程并确保资源释放是开发者面临的重要挑战。直接终止线程可能导致内存泄漏、文件未关闭等问题。POSIX 线程库提供了一套完整的线程取消和清理机…...

FPGA学习篇——Verilog学习之寄存器的实现

1 寄存器理论 这里在常见的寄存器种加了一个复位信号sys_rst_n。&#xff08;_n后缀表示复位信号低电平有效&#xff0c;无这个后缀的则表示高电平有效&#xff09; 这里规定在时钟的上升沿有效&#xff0c;只有当时钟的上升沿来临时&#xff0c;输出out 才会改变&#xff0c;…...

Cursor异常问题全解析-无限使用

title: Cursor异常问题全解析无限使用 tags: cursor categories:aiai编程 mathjax: true description: Cursor异常问题全解析与解决方案大全 abbrlink: 64908bd0 date: 2025-03-19 14:48:32 &#x1f916; Assistant &#x1f6a8; Cursor异常问题全解析与解决方案大全 &…...

【VUE】ant design vue实现表格table上下拖拽排序

适合版本&#xff1a;ant design vue 1.7.8 实现效果&#xff1a; 代码&#xff1a; <template><div class"table-container"><a-table:columns"columns":dataSource"tableData":rowKey"record > record.id":row…...

Vue实现动态数据透视表(交叉表)

需求:需要根据前端选择的横维度、竖维度、值去生成一个动态的表格&#xff0c;然后把交叉的值放入到对应的横维度和竖维度之下&#xff0c;其实就是excel里面的数据透视表功能&#xff0c;查询交叉语句为sql语句。 实现页面&#xff1a; 选择一下横维度、竖维度、值之后点击查…...

推荐《人工智能算法》卷1、卷2和卷3 合集3本书(附pdf电子书下载)

今天&#xff0c;咱们就一同深入探讨人工智能算法的卷1、卷2和卷3&#xff0c;看看它们各自蕴含着怎样的奥秘&#xff0c;并且附上各自的pdf电子版免费下载地址。 《人工智能算法&#xff08;卷1&#xff09;&#xff1a;基础算法》 下载地址&#xff1a;https://www.panziye…...