【LuaFramework】服务器模块相关知识

server/2024/12/27 4:39:37/

目录

一、客户端代码

二、本地服务器代码

三、解决服务器无法多次接收客户端消息问题


一、客户端代码

连接本地服务器127.0.0.1:2012端口(如何创本地服务器,放最后说),连接成功后会回调

协议号Connect是101,其他如下,将这个Connect协议号和数据(空的字节流)放入一个mEvents队列,等待Update执行(目的应该是回到主线程才执行回调,避免一些问题)

这里Update方法就是Monobehaviour的生命周期Update,它简单地遍历队列逐个出队派发事件“DISPATCH_MESSAGE”去到如下

再回到调用lua的Network.OnSocket方法并且将 buffer.Key(协议号 101) 和 buffer.Value(空) 数据传递。

Network.OnSocket继续派发协议号作为事件名,执行OnConnect方法,至此完成一整套连接流程

其他相关的事件可以查如下找到相关的代码

由于我们lua侧仅写了1个消息协议号'104' 所以本地服务器代码也是要用104作为协议号传递,不然接收消息检测不到是104就无法正常通过消息派发并执行到对应的lua消息回调代码。

接收消息回调

TestProtoType有很多种传递消息的方式,项目默认使用ProtocalType.BINARY

好绕,最终是到了上面的WriteMessage方法,发送是以"消息长度"+"消息内容"为一条字节流传递到服务器,执行完后回调OnWrite方法

二、本地服务器代码

using System;
using System.Net;
using System.Net.Sockets;namespace SimpleNet
{class Program{static void Main(string[] args){Console.WriteLine("Hello World!");//Socket  tcpSocket listenfd = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);//bindIPAddress ipAdr = IPAddress.Parse("127.0.0.1");IPEndPoint ipEp = new IPEndPoint(ipAdr, 2012);listenfd.Bind(ipEp);//listenlistenfd.Listen(0);Console.WriteLine("启动服务器成功");while (true){//AcceptSocket connfd = listenfd.Accept();Console.WriteLine("服务器Accept");//Recv 测试byte[] readBuff = new byte[100];int count = connfd.Receive(readBuff);//steamstring showStr = "";for(int i = 0; i< count; i++){int b = (int)readBuff[i];showStr += b.ToString() + " ";}Console.WriteLine("字节流:" + showStr);//解析Int16 msgLen = BitConverter.ToInt16(readBuff, 0);Int16 protocal = BitConverter.ToInt16(readBuff, 2);Int16 strLen = BitConverter.ToInt16(readBuff, 5);//具体还要看字节流输出来读取第几个字节是长度,若读错了下一行会报错string str = System.Text.Encoding.UTF8.GetString(readBuff, 6, strLen);Console.WriteLine("消息长度:" + msgLen);Console.WriteLine("协议号:" + protocal);Console.WriteLine("字符串:" + str);//send 原样返回byte[] writeBuff = new byte[count];Array.Copy(readBuff, writeBuff, count);connfd.Send(writeBuff);}}}
}

客户端接收到服务器消息的打印,服务器是直接将客户端的消息拷贝了一份再发送给客户端。

跑代码时发现有些lua报错:FindChild相关不存在

--初始化面板--
function MessagePanel.InitPanel()--this.btnClose = transform:FindChild("Button").gameObject; --bug代码 FindChild是不存在的接口...this.btnClose = transform:Find("Button").gameObject;
end

三、解决服务器无法多次接收客户端消息问题

测试发现上面的服务器代码不支持多次发送和接收消息,可以修改为如下服务器代码解决:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;namespace SimpleNet
{class Program{static async Task Main(string[] args){SimpleTcpServer server = new SimpleTcpServer("127.0.0.1", 2012);await server.StartAsync();                       }}
}
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;namespace SimpleNet
{public class SimpleTcpServer{private TcpListener _listener;private string _ip;private int _port;        public SimpleTcpServer(string ip, int port){_ip = ip;_port = port;}public async Task StartAsync(){_listener = new TcpListener(IPAddress.Parse(_ip), _port);_listener.Start();Console.WriteLine($"Server started on port {_port}.");while (true){TcpClient client = await _listener.AcceptTcpClientAsync();_ = HandleClientAsync(client);}}private async Task HandleClientAsync(TcpClient client){NetworkStream stream = client.GetStream();byte[] readBuff = new byte[1024];while (true){try{int count = await stream.ReadAsync(readBuff, 0, readBuff.Length);if (count == 0) // Client disconnected{break;}                    //steamstring showStr = "";for (int i = 0; i < count; i++){int b = (int)readBuff[i];showStr += b.ToString() + " ";}Console.WriteLine("字节流:" + showStr);//解析Int16 msgLen = BitConverter.ToInt16(readBuff, 0);Int16 protocal = BitConverter.ToInt16(readBuff, 2);Int16 strLen = BitConverter.ToInt16(readBuff, 5);string str = System.Text.Encoding.UTF8.GetString(readBuff, 7, strLen);Console.WriteLine("消息长度:" + msgLen);Console.WriteLine("协议号:" + protocal);Console.WriteLine("字符串:" + str);//send 原样返回byte[] writeBuff = new byte[count];Array.Copy(readBuff, writeBuff, count);await stream.WriteAsync(writeBuff, 0, writeBuff.Length);}catch (Exception ex){Console.WriteLine("Error: " + ex.Message);break;}}client.Close();}public void Stop(){_listener.Stop();}}
}

http://www.ppmy.cn/server/153525.html

相关文章

【ES6复习笔记】rest参数(7)

什么是 rest 参数&#xff1f; rest 参数是 ES6 引入的一个特性&#xff0c;它允许我们将一个不定数量的参数表示为一个数组。使用 rest 参数可以更方便地处理函数的参数&#xff0c;尤其是在参数数量不确定的情况下。 如何使用 rest 参数&#xff1f; 在函数定义中&#xf…

Debezium日常分享系列之:Debezium Engine

Debezium日常分享系列之&#xff1a;Debezium Engine 依赖打包项目在代码中输出消息格式消息转换消息转换谓词高级记录使用引擎属性异步引擎属性数据库模式历史属性处理故障 Debezium连接器通常通过部署到Kafka Connect服务来运行&#xff0c;并配置一个或多个连接器来监视上游…

【项目介绍】基于机器学习的低空小、微无人机识别技术

文章目录 1.项目介绍2.数据预处理3.特征选取4.模型训练参考文献 1.项目介绍 对于现代雷达探测系统而言&#xff0c;无人机和飞鸟同属于低空小、微特征的一类典型目标&#xff0c;而面对比较复杂的环境&#xff0c;如何有效区分两者类型并完成识别是当下急迫且重要的难题。常规…

Docker部署GitLab服务器

一、GitLab介绍 1.1 GitLab简介 GitLab 是一款基于 Git 的开源代码托管平台&#xff0c;集成了版本控制、代码审查、问题跟踪、持续集成与持续交付&#xff08;CI/CD&#xff09;等多种功能&#xff0c;旨在为团队提供一站式的项目管理解决方案。借助 GitLab&#xff0c;开发…

2024.12.25在腾讯云服务器上使用docker部署flask

2024.12.25在腾讯云服务器上使用docker部署flask 操作系统&#xff1a;Ubuntu 根据腾讯云的说明文档安装 Docker 并配置镜像加速源&#xff0c;注意需要安装腾讯云的加速源&#xff0c;使用官网的加速源连接极其不稳定&#xff0c;容易导致运行失败。使用哪个公司的云服务器就…

MySQL for update skip locked 与 for update nowait

理论&#xff08;下方有实操&#xff09; for update skip locked 官方文档&#xff1a;https://dev.mysql.com/doc/refman/8.0/en/innodb-locking-reads.html#innodb-locking-reads-for-update语法&#xff1a;select语句后跟 for update skip locked作用&#xff1a;目标对…

面试题整理(四)

1.Max transition,leakage优化,hold time ,setup time violation修复的顺序是? 答:先把max transition修复掉,如果max transition有violation,意味着其超出了查找表范围之外,所以计算得到的delay都不是很准的。 其次是把setup修复了,因为setup相对来说,需要减少cell…

Nginx单向链表 ngx_list_t

目录 基本概述 数据结构 接口描述 具体实现 ngx_list_create ngx_list_init ngx_list_push 使用案例 整理自 nginx 1.9.2 源码 和 《深入理解 Nginx&#xff1a;模块开发与架构解析》 基本概述 Nginx 中的 ngx_list_t 是一个单向链表容器&#xff0c;链表中的每一个节…