GO网络编程(六):海量用户通信系统4:读写数据包与登录消息处理

ops/2024/10/21 7:56:01/

如果你掌握了前三节,接下来就会轻松很多,看老韩的视频也不容易蒙圈了。本节内容不难,分别是读写数据包和登录消息处理。注意,因为上一节(GO网络编程五)把系统框架,目录结构和业务流程都讲了,所以从本节开始,内容会比之前简略。

一、读写数据包

读数据包
总体流程:
1.准备缓冲区
2.读取消息头部并存入缓冲区
3.将缓冲区的消息头部转换成消息长度
4.根据消息长度读取消息内容
5.将消息内容反序列化并返回
代码

// 可以自定义错误变量err,即定义一个新的err,写入自定义的错误内容,
// 但考虑到上层可能要判断err的原本的类型,所以这里直接返回err
// 读数据包
func ReadPkg(conn net.Conn) (mes message.Message, err error) {fmt.Println("读数据包...")buf := make([]byte, 1024*4) //1.准备缓冲区//后续可能会读取更多字节,所以缓冲区大小一般都设置得比较大//2.读取消息头部并存入缓冲区n, err := conn.Read(buf[:4])//conn.Read 在conn没有被关闭的情况下,才会阻塞//如果客户端关闭了conn,则不会阻塞if n != 4 || err != nil {//因为服务端要通过判断err的类型来提示客户端关闭,所以这里什么都不做return}//3.将缓冲区的消息头部转换成消息长度var pkgLen = binary.BigEndian.Uint32(buf[:4])//4.根据消息长度读取消息内容n, err = conn.Read(buf[:pkgLen])if n != int(pkgLen) || err != nil {fmt.Println("conn.Read error")return}//5.将消息内容反序列化并返回err = json.Unmarshal(buf[:pkgLen], &mes)//由于 mes 是在函数签名中命名的返回值变量,Go 自动为它创建了一个//初始的 message.Message 类型实例,这样就无需显式声明if err != nil {fmt.Println("read pkg body error,json.Unmarshal error")return}return
}

总体流程:
1.准备缓冲区
2.根据消息内容获取消息长度
3.将消息长度存入缓冲区
4.发送消息长度
5.发送消息内容
代码

// 写数据包
func WritePkg(conn net.Conn, data []byte) (err error) {fmt.Println("写数据包...")buf := make([]byte, 4) //1.准备缓冲区//2.根据消息内容获取消息长度var pkgLen = uint32(len(data))//3.将消息长度存入缓冲区binary.BigEndian.PutUint32(buf, pkgLen)//4.发送消息长度n, err := conn.Write(buf)if n != 4 || err != nil {fmt.Println("conn.Write error")return}//5.发送消息内容n, err = conn.Write(data)if n != int(pkgLen) || err != nil {fmt.Println("conn.Write error")return}return
}

二、登录消息处理

总体流程:
1.先从反序列消息,存在登录消息结构体
2.初始化消息结构体和创建登录响应结构体。
3.判定登录消息结构体的信息并初始化登录响应结构体。
4.序列化登录响应结构体并初始化消息结构体
5.发送消息
代码

// 处理登录消息
func serverProcessLogin(conn net.Conn, mes *message.Message) (err error) {//1.先从mes中取出mes.Data,并直接反序列化成LoginMesvar loginMes message.LoginMeserr = json.Unmarshal([]byte(mes.Data), &loginMes)if err != nil {fmt.Println("json.Unmarshal error:")return}//1初始化一个Mes 结构体var resMes message.MessageresMes.Type = message.LoginResMesType//2创建一个LoginResMes 结构体var loginResMes message.LoginResMes//如果用户id=100,密码=123456,认为合法,否则不合法if loginMes.UserID == 100 && loginMes.UserPwd == "123456" {//合法loginResMes.Code = 200} else {//不合法loginResMes.Code = 500 //状态码,表示该用户不存在loginResMes.Error = "该用户不存在,请注册再使用"}//3 将loginResMes序列化data, err := json.Marshal(loginResMes)if err != nil {fmt.Println("json.Marshal error:")return}//4.将序列化后的loginResMes作为给resMes的dataresMes.Data = string(data)//5.对resMes进行序列化,准备发送data, err = json.Marshal(resMes)if err != nil {fmt.Println("json.Marshal error:")return}//6.发送消息err = utils.WritePkg(conn, data)if err != nil {fmt.Println("WritePkg(conn) error:")return}return
}

http://www.ppmy.cn/ops/123402.html

相关文章

[已解决] Install PyTorch 报错 —— OpenOccupancy 配环境

目录 关于 常见的初始化报错 环境推荐 torch, torchvision & torchaudio cudatoolkit 本地pip安装方法 关于 OpenOccupancy: 语义占用感知对于自动驾驶至关重要,因为自动驾驶汽车需要对3D城市结构进行细粒度感知。然而,现有的相关基准在城市场…

人机协作:科技与人类智慧的融合

随着科技的飞速发展,越来越多的领域开始借助人工智能(AI)和自动化技术来提升工作效率。人机协作(Human-Machine Collaboration)这一概念逐渐成为现代技术进步的核心。它不仅改变了我们的工作方式,也在重新定…

【mysql 截断订单表order 报错】

truncate table order;这个是一个截断订单表的sql语句 看起来没有什么问题 但是实际执行的时候是会报错的 SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version…

如何通俗的理解linux中的挂载?

挂载点(Mount Point)是操作系统中用于将一个文件系统连接到现有目录结构中的特定目录。理解挂载点对于管理和组织文件系统、分区以及外部存储设备(如硬盘、U盘、网络驱动器等)至关重要。以下是对挂载点的详细解释,以帮…

基于springboot的公司财务管理系统(含源码+sql+视频导入教程+文档+PPT)

👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于springboot的公司财务管理系统拥有两种角色 管理员:员工管理、部门管理、工资管理、资产管理、经营管理、利润管理等 员工:查看工资、查看公告、登录注册 1.…

springboot分组校验

把校验项进行归类分组,在完成不同的功能的时候,校验组中的校验项 1.定义分组 2.定义校验项时指定归属的分组 3.校验时指定要校验的分组 NotNull中group的添加以及 public interface Add{} import com.fasterxml.jackson.annotation.JsonFormat; im…

枚举+二分,CF 325B - Stadium and Games

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 325B - Stadium and Games 二、解题报告 1、思路分析 考虑 一个可能的初…

Python大数据学习之Hadoop学习——day08_hive函数

一.hive查询 语法结构: SELECT [ALL | DISTINCT] 字段名,字段名,... FROM 表名 [inner | left outer | right outer | full outer | left semi join 表名 on 关联条件] [where 非聚合条件] [GROUP BY 分组字段名] [HAVING 聚合条件] [ORDER BY 排序字段…