GameNetController网络控制器

 好用的局域网内的网络控制器,稍作更改可连接互联网

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using LitJson;
using UnityEngine;
using Random = UnityEngine.Random;public struct UdpMessage
{public string format;public string usingName;public Dictionary<string,string> getString;public Dictionary<string, List<string>> getStringList;public Dictionary<string, Dictionary<string, string>> getStringDictionary;public UdpMessage(string format,string usingName){this.format = format;this.usingName = usingName;getString = new Dictionary<string, string>();getStringList = new Dictionary<string, List<string>>();getStringDictionary = new Dictionary<string, Dictionary<string, string>>();}public UdpMessage SetString(Dictionary<string,string> setString){getString = setString;return this;}public UdpMessage SetStringList(Dictionary<string, List<string>> setStringList){getStringList = setStringList;return this;}public UdpMessage SetStringDictionary(Dictionary<string, Dictionary<string, string>> setStringDictionary){getStringDictionary = setStringDictionary;return this;}
}public struct HandleMessage
{public UdpMessage message;public IPEndPoint endPoint;public HandleMessage(UdpMessage message,IPEndPoint endPoint){this.message = message;this.endPoint = endPoint;}
}public class GameNetController
{private static GameNetController main;public static GameNetController Main{get{if (main == null){main = new GameNetController();UnitManager.Main.GameNetOpen();}return main;}}private UdpClient severClient;private Thread messageThread;public bool isLocalPlayer = true;public Dictionary<string, List<HandleMessage>> messageList = new Dictionary<string, List<HandleMessage>>();public Dictionary<string, IPEndPoint> allClient = new Dictionary<string, IPEndPoint>();public Dictionary<string, Action<UdpMessage,IPEndPoint>> severAction = new Dictionary<string, Action<UdpMessage,IPEndPoint>>();public Dictionary<string, Action<UdpMessage,IPEndPoint>> clientAction = new Dictionary<string, Action<UdpMessage,IPEndPoint>>();public void SeverInit(){isLocalPlayer = false;severClient = new UdpClient(new IPEndPoint(IPAddress.Any, int.Parse(UnitManager.Main.GetLocalText("连接端口"))));messageThread = new Thread(SeverListenMessage);messageThread.Start();}private IPEndPoint mainPoint, severPoint;private UdpClient mainClient;public void ClientInit(){isLocalPlayer = false;mainPoint = new IPEndPoint(IPAddress.Any, Random.Range(20000,60000));severPoint = new IPEndPoint(IPAddress.Parse(UnitManager.Main.GetLocalText("管理员地址")), int.Parse(UnitManager.Main.GetLocalText("连接端口")));mainClient = new UdpClient(mainPoint);messageThread = new Thread(ClientListenMessage);messageThread.Start();}private byte[] bytes;private IPEndPoint endPoint;private UdpMessage message;private Dictionary<string, string> getPacket = new Dictionary<string, string>();void ClientListenMessage(){while (true){bytes = mainClient.Receive(ref endPoint);string getStr = Encoding.UTF8.GetString(bytes);if (getStr.Contains("packet")){if (!getPacket.ContainsKey(getStr.Split('^')[0].Split(':')[1])){getPacket.Add(getStr.Split('^')[0].Split(':')[1],"");}getPacket[getStr.Split('^')[0].Split(':')[1]] += getStr.Split('^')[1];if(getStr.Split('^')[0].Split(':')[0] == "packet"){continue;}if(getStr.Split('^')[0].Split(':')[0] == "packetEnd"){getStr = getPacket[getStr.Split('^')[0].Split(':')[1]];getPacket.Remove(getStr.Split('^')[0].Split(':')[1]);}}message = JsonMapper.ToObject<UdpMessage>(getStr);if (!messageList.ContainsKey(message.format)){messageList.Add(message.format,new List<HandleMessage>());}messageList[message.format].Add(new HandleMessage(message,endPoint));}}void SeverListenMessage(){while (true){    bytes = severClient.Receive(ref endPoint);string getStr = Encoding.UTF8.GetString(bytes);if (getStr.Contains("packet")){Debug.LogError("接收到数据包" + getStr.Split('^')[0]);if (!getPacket.ContainsKey(getStr.Split('^')[0].Split(':')[1])){getPacket.Add(getStr.Split('^')[0].Split(':')[1],"");}getPacket[getStr.Split('^')[0].Split(':')[1]] += getStr.Split('^')[1];if(getStr.Split('^')[0].Split(':')[0] == "packet"){Debug.LogError("接收到过度数据包" + getStr.Split('^')[0]);continue;}if(getStr.Split('^')[0].Split(':')[0] == "packetEnd"){Debug.LogError("接收到终结数据包" + getStr.Split('^')[0]);getStr = getPacket[getStr.Split('^')[0].Split(':')[1]];getPacket.Remove(getStr.Split('^')[0].Split(':')[1]);}}message = JsonMapper.ToObject<UdpMessage>(getStr);if (!messageList.ContainsKey(message.format)){messageList.Add(message.format,new List<HandleMessage>());}messageList[message.format].Add(new HandleMessage(message,endPoint));if (message.usingName != "" && !allClient.ContainsKey(message.usingName)){allClient.Add(message.usingName, endPoint);}if (message.usingName != "" && allClient.ContainsKey(message.usingName)){allClient[message.usingName] = endPoint;}}}public void ClientSendMessage(UdpMessage message){string str = JsonMapper.ToJson(message);if (str.Length > 10000){int number = Random.Range(0, int.MaxValue);string getStr = "";List<string> strList = new List<string>();while (true){if (str.Length > 10000){getStr = "packet:" + number + "^";getStr += str.Substring(0, 10000);strList.Add(getStr);str = str.Remove(0, 10000);}else{getStr = "packetEnd:" + number + "^";getStr += str.Substring(0, str.Length);strList.Add(getStr);break;}}for (int i = 0; i < strList.Count; i++){byte[] bytes = Encoding.UTF8.GetBytes(strList[i]);UnitManager.Main.Wait(i*0.1f, () =>{try{mainClient.Send(bytes, bytes.Length, severPoint);}catch (Exception e) { Debug.LogError(e); }});}}else{bytes = Encoding.UTF8.GetBytes(str);try{mainClient.Send(bytes, bytes.Length, severPoint);}catch (Exception e) { Debug.LogError(e); }}}public void SeverSendMessage(UdpMessage message){string str = JsonMapper.ToJson(message);if (str.Length > 10000){int number = Random.Range(0, int.MaxValue);string getStr = "";List<string> strList = new List<string>();while (true){if (str.Length > 10000){getStr = "packet:" + number + "^";getStr += str.Substring(0, 10000);strList.Add(getStr);str = str.Remove(0, 10000);}else{getStr = "packetEnd:" + number + "^";getStr += str.Substring(0, str.Length);strList.Add(getStr);break;}}for (int i = 0; i < strList.Count; i++){byte[] bytes = Encoding.UTF8.GetBytes(strList[i]);UnitManager.Main.Wait(i*0.1f, () =>{foreach (var client in allClient){try{severClient.Send(bytes, bytes.Length, client.Value);}catch (Exception e) { Debug.LogError(e); }}});}}else{bytes = Encoding.UTF8.GetBytes(str);foreach (var client in allClient){try{severClient.Send(bytes, bytes.Length, client.Value);}catch (Exception e) { Debug.LogError(e); }}}}public void SeverSendMessage(IPEndPoint endPoint,UdpMessage message){string str = JsonMapper.ToJson(message);if (str.Length > 10000){int number = Random.Range(0, int.MaxValue);string getStr = "";List<string> strList = new List<string>();while (true){if (str.Length > 10000){getStr = "packet:" + number + "^";getStr += str.Substring(0, 10000);strList.Add(getStr);str = str.Remove(0, 10000);}else{getStr = "packetEnd:" + number + "^";getStr += str.Substring(0, str.Length);strList.Add(getStr);break;}}for (int i = 0; i < strList.Count; i++){byte[] bytes = Encoding.UTF8.GetBytes(strList[i]);UnitManager.Main.Wait(i*0.1f, () =>{try{severClient.Send(bytes, bytes.Length, endPoint);}catch (Exception e) { Debug.LogError(e); }});}}else{bytes = Encoding.UTF8.GetBytes(str);try{severClient.Send(bytes, bytes.Length, endPoint);}catch (Exception e) { Debug.LogError(e); }}}public void SeverSendMessage(List<string> sendNames,UdpMessage message){foreach (string sendName in sendNames){SeverSendMessage(allClient[sendName],message);}}
}

同时找一个继承MonoBehaviour的类添加一段Update来处理接收到的数据

private bool gameNetOpen;public void GameNetOpen(){gameNetOpen = true;}private void Update(){if(!gameNetOpen){return;}if(GameNetController.Main.messageList.Count == 0){return;}foreach (var message in GameNetController.Main.messageList){if (GameNetController.Main.severAction.ContainsKey(message.Key)){foreach (HandleMessage handleMessage in message.Value){try{GameNetController.Main.severAction[message.Key](handleMessage.message,handleMessage.endPoint);}catch{}}GameNetController.Main.messageList.Remove(message.Key);return;}if (GameNetController.Main.clientAction.ContainsKey(message.Key)){foreach (HandleMessage handleMessage in message.Value){try{GameNetController.Main.clientAction[message.Key](handleMessage.message,handleMessage.endPoint);}catch{}}GameNetController.Main.messageList.Remove(message.Key);return;}}GameNetController.Main.messageList.Clear();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/189357.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】拆分详解 - 堆的应用

堆的应用 1. 堆排序 思路&#xff1a; 建大堆 向下调整建堆&#xff0c;根位置即选出的最大数 排序&#xff1a;交换头尾&#xff0c;向下调整&#xff0c;尾删 把大数移到尾部&#xff0c;调整堆&#xff0c;将排好的大数“删出”堆注意向下调整和尾删顺序不能对调&#xff0c…

cocos 关于多个摄像机,动态添加节点的显示问题,需要动态修改layer。(跟随摄像机滚动)(神坑官网也不说明一下)

参考文章&#xff1a;Cocos 3.x 层级Layer - 简书 2D镜头跟随应该怎么实现呢 - Creator 3.x - Cocos中文社区 关于多个摄像机&#xff0c;动态添加节点的显示问题&#xff0c;需要动态修改layer&#xff1f; 场景&#xff1a;在制作摄像机跟随角色移动功能时&#xff0c;新增…

Python 3 使用 read()、readline()、readlines() 函数 读取文件

1 样例文件 example.txt 春晓 孟浩然〔唐代〕 春眠不觉晓&#xff0c;处处闻啼鸟。 夜来风雨声&#xff0c;花落知多少。 2 分别使用 read()、readline()、readlines() 函数 2.1 # read() -------- 一次性读取所有文本&#xff0c;以字符串的形式返回结果。 # read() ----…

1.qml-3D入门讲解介绍

本章我们来学习QML 3D教程&#xff0c;QML 3D能够支持windows linux等多平台跨平台并且显示效果大部分一致&#xff0c;非常方便&#xff0c;学习的qt版本最低为qt6.5。 要使用qml 3D类&#xff0c;需要导入QtQuick3D模块。 这是使用空间渲染器和场景图的 QML 前端。目前&…

SQL Server 2016(分离和附加数据库)

1、实验环境。 基于上一个实验《SQL Server&#xff08;创建数据库&#xff09;》 2、需求描述。 class数据库的数据文件和事务日志文件都位于C:\db_class目录下。现在需要把class数据库的数据文件和事务日志文件分开存放&#xff0c;数据文件class.mdf存放于原位置&#xff0…

网传滴滴系统崩了,是因为k8s版本升级错误?

11月27日晚间&#xff0c;滴滴因系统故障导致App服务异常登上热搜&#xff0c;不仅无法显示定位、无法打车&#xff0c;有司机的后台还显示收入超690亿。28日和29日&#xff0c;滴滴两次发文致歉&#xff0c;称初步确定事故起因是底层系统软件发生故障。 相较于一些网友戏谑的…

vue和react使用上的不同

使用表达式 **react使用js表达式** const name 李四 <h1>你好&#xff0c;我叫{name}</h1> **vue 使用表达式** const name 李四 <div>你好&#xff0c;我叫{{name}}</div>列表渲染 列表渲染 const songs [{ id: 1, name: 痴心绝对 },{ id: 2, n…

Android 应用程序无响应定位ANR原因

废话不多说&#xff0c;直接上方案&#xff1a; 第一步&#xff1a; 执行adb命令 adb bugreport /Users/mac/Desktop/anr 解压后FS/data/anr下就会有相关anr文件 /Users/mac/Desktop/anr 是电脑存储文件的路径&#xff0c;可以随便定义&#xff0c;这个没有影响。我的电脑是…

人工智能-优化算法之学习率调度器

学习率调度器 到目前为止&#xff0c;我们主要关注如何更新权重向量的优化算法&#xff0c;而不是它们的更新速率。 然而&#xff0c;调整学习率通常与实际算法同样重要&#xff0c;有如下几方面需要考虑&#xff1a; 首先&#xff0c;学习率的大小很重要。如果它太大&#xf…

Todesk 无法登录,无法联网

前言 我习惯用todesk远程ubuntu&#xff0c;但是突然发现掉线了&#xff0c;但是ssh还能连接 问题查找 1.ping 一下主机ip 2.ssh连接后&#xff0c;ping 一下百度&#xff0c;查看是否外网正常 3.输入一下命令 ps -ef | grep todesk #查看todesk 进程 sudo kill -9 ....…

快速掌握Pyqt5的20种输入控件(Input Widgets)

Pyqt5相关文章: 快速掌握Pyqt5的三种主窗口 快速掌握Pyqt5的2种弹簧 快速掌握Pyqt5的5种布局 快速弄懂Pyqt5的5种项目视图&#xff08;Item View&#xff09; 快速弄懂Pyqt5的4种项目部件&#xff08;Item Widget&#xff09; 快速掌握Pyqt5的6种按钮 快速掌握Pyqt5的10种容器&…

HTML5 的全局属性 hidden 和 display:none 的关系

目录 1&#xff0c;hidden 和 display:none 的关系2&#xff0c;其他隐藏元素的方式2.1&#xff0c;语意上的隐藏2.2&#xff0c;视觉上的隐藏 1&#xff0c;hidden 和 display:none 的关系 hidden - MDN 参考 一句话总结&#xff1a;hidden 是HTML5 新增的全局布尔属性&…

Centos7使用阿里云镜像加速服务安装Docker

文章目录 一、前提说明二、安装docker1、创建docker文件夹2、安装所需的软件包3、设置Docker仓库4、安装docker5、启动验证使用阿里云镜像加速服务 三、卸载docker 一、前提说明 需要先安装好虚拟机&#xff0c;可以查看这篇https://blog.csdn.net/qq_36433289/article/detail…

Python批处理PDF文件,PDF附件轻松批量提取

PDF附件是指在PDF文档中嵌入的其他文件&#xff0c;如图像、表格、音频、视频或其他文档。这些附件可以与PDF文档一起存储、传输和共享&#xff0c;为文档提供了更丰富的内容和更多的功能。通过添加附件&#xff0c;我们可以将相关文件和信息捆绑在一起&#xff0c;使其更易于管…

Verilog 入门(五)数据流模型化

文章目录 连续赋值语句时延 连续赋值用于数据流行为建模&#xff1b;相反&#xff0c;过程赋值用于顺序行为建模。组合逻辑电路的行为最好使用连续赋值语句建模。 连续赋值语句 连续赋值语句将值赋给线网&#xff08;连续赋值不能为寄存器赋值&#xff09;&#xff0c;它的格式…

Linux 只能收到 SYN 包 不能回包

如果用户发现云主机不能登录&#xff0c;例如无法远程 22 端口或其他端口&#xff0c;但是更换网络环境正常&#xff0c;服务端抓包发现客户端发包只有 SYN&#xff0c;没有回包&#xff0c;可以执行 netstat -s |grep rejec 查看下是否是 tcp_timestamps 的问题 [roothfgo2 ~…

Java的53个关键字分类及详细说明(包含3个特殊直接量+2个保留字)

文章目录 关键字,特殊直接量&#xff0c;保留字关键字的详细用法说明&#xff08;1&#xff09;访问控制类关键字&#xff08;2&#xff09;修饰符类关键字&#xff08;3&#xff09;程序控制类关键字&#xff08;4&#xff09;错误处理类关键字&#xff08;5&#xff09;包相关…

Python+Requests模拟发送GET请求

模拟发送GET请求 前置条件&#xff1a;导入requests库 一、发送不带参数的get请求 代码如下&#xff1a; 以百度首页为例 import requests# 发送get请求 response requests.get(url"http://www.baidu.com") print(response.content.decode("utf-8"))…

Drift plus penalty 漂移加惩罚Part2——性能分析

文章目录 正文Performance analysisAverage penalty analysis 平均惩罚分析Average queue size analysis 平均队列大小分析Probability 1 convergenceApplication to queues with finite capacityTreatment of queueing systemsConvex functions of time averages Delay tradeo…

SSR是什么?Vue中怎么实现?

一、是什么 概念 SSR是指服务器端渲染&#xff08;Server-Side Rendering&#xff09;&#xff0c;是一种将客户端和服务器端合并的 Web 应用程序渲染技术。在 SSR 中&#xff0c;应用程序的 UI 在服务器端渲染完成后&#xff0c;再将整个渲染好的 HTML、CSS 和 JavaScript 发…