Netty聊天系统(1)通过自定义协议实现客户端与服务器端通信

2023-11-14

1 自定义实现客户端与服务器端通信的协议

1.1 通信协议的设计

自定义的通信协议需要哪些内容

1)魔数:第一个字段一般是魔数,一般固定的几个字节。一个PNG图片的编码中有固定数量固定内容的字节,用于表示这是一个PNG图片;Java的Class文件打头有一串魔数用于表示这是一个class文件;同样,我们的通信协议也是这么定义,服务器端或客户端收到数据包之后,会先读取魔数看看是不是我们定义的通信协议,只有是我们的通信协议时才能按照我们定义的规则正确读取数据。

2)版本号:用于一个字节表示,比如Http协议有1.0/1.1/2.0版本,用于标识当前的数据包使用的是哪个版本号

3)序列化算法:我们Netty通信过程中,使用Java对象进行数据传输,就一定会涉及到序列化与反序列化,用一个字节说明采用哪种序列化方式。

4)指令:你发给我这个数据包时要干什么。比如TCP协议中,SYN位置1就代表我是要跟你建立连接、FIN位置1就是代表我要断开连接。在聊天系统中,服务器收到客户端的数据包,指令位用于说明客户端发送这条数据包的目的,是要给某人发送消息呢还是要添加某人为好友呢还是怎么的…

5)数据长度:我发送给你的数据包的数据部分的长度是多少。解决TCP粘包拆包问题

6)数据部分:传输的数据

image-20200729102904574

1.2 通信协议的实现

1.2.1 Java对象

1)定义通信过程中传输的Java对象的抽象类

package maolaoke.top.netty.protocol;

import lombok.Data;

@Data
public abstract class Packet {
   
    //协议版本
    private Byte version = 1;

    //获取指令
    public abstract Byte getCommand();
}

2)~~定义一个枚举类,列出所有的指令。~~定义一个Command接口来模拟枚举,因为枚举默认是Integer类型,而我们要传输的是一个字节,用Byte来表示更合适。

public interface Command {
   
    Byte LOGIN_REQUEST = 1;  //表示这是一个登录请求
}

登录请求的Java类定义:

import maolaoke.top.netty.protocol.Command;

public class LoginRequestPacket  extends Packet{
   
    private Integer userId;

    private String username;

    private String password;
    
    @Override
    public Byte getCommand() {
   
        return Command.LOGIN_REQUEST;
    }
}

1.2.2 序列化

1)定义一个接口来模拟枚举,枚举所有的序列化标识。

public interface SerializerAlgorithm {
   
    byte JSON_SERIALIZER = 1;  //JSON序列化
}

2)定义一个序列化接口

public interface Serializer {
   
    //获取序列化方式
    byte getSerializerAlgorithm();

    //序列化方法
    byte[] serialize(Object object);

    //反序列化
    <T> T deserialize(Class<T> clazz, byte[] bytes);
}

3)实现JSON方式的序列化。

导入fastJson依赖包。

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.47</version>
</dependency>
import com.alibaba.fastjson.JSON;

public class JsonSerializer implements Serializer {
   
    @Override
    public byte getSerializerAlgorithm(){
   
        return SerializerAlgorithm.JSON_SERIALIZER;
    }

    @Override
    public byte[] serialize(Object object) {
   
        return JSON.toJSONBytes(object);
    }

    @Override
    public <T> T deserialize(Class<T> clazz, byte[] bytes) {
   
        return JSON.parseObject(bytes, clazz);
    }
}

1.2.3 编解码

PacketCodeC.java实现编解码,将发送的Java对象编码成标准的自定义通信协议的格式,将接收到的数据包解码成ByteBuf。

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import maolaoke.top.netty.protocol.Command;
import maolaoke.top.netty.protocol.packet.LoginRequestPacket;
import maolaoke.top.netty.protocol.packet.Packet;
import maolaoke.top.netty.protocol.serializer.JsonSerializer;
import maolaoke.top.netty.protocol.serializer.Serializer;

import java.util.HashMap;
import java.util.Map;

public class PacketCodeC {
   
    private 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Netty聊天系统(1)通过自定义协议实现客户端与服务器端通信 的相关文章

随机推荐

  • LeetCode 热题 HOT 100:滑动窗口专题

    LeetCode 热题 HOT 100 https leetcode cn problem list 2cktkvj 文章目录 3 无重复字符的最长子串 128 最长连续序列 239 滑动窗口最大值 438 找到字符串中所有字母异位词 3
  • JFLex和JavaCUP简单使用

    由于需要使用到doris中的sql parser功能 所以决定使用其定义好的flex文件和cup文件 生成自己sqlscanner和parser类 步骤如下 1 下载JFlex和JavaCUP程序 路径分别为 https www jflex
  • 机械制造与自动化涉及使用计算机吗,论机械设计制造及自动化中计算机技术

    将计算机技术运用到机械设计制造中 大大提高了机械设计制造智能化水平 在机械设计制造中占据很重要的位置 但我国机械制造设计水平同国外发达国家相比 还存在一定的距离 若是可以加大对计算机技术的研究和探索 对机械制造行业的发展是非常有利的 1机械
  • Flowable入门系列文章29 - Activity解读 05

    1 消息开始事件 描述 甲消息开始事件可用于使用已命名的信息来启动一个过程实例 这有效地允许我们使用消息名称从一组替代开始事件中选择正确的开始事件 在部署具有一个或多个消息启动事件的流程定义时 应考虑以下注意事项 消息开始事件的名称在给定的
  • 机器学习实战:Python基于支持向量机SVM-RFE进行分类预测(三)

    文章目录 1 前言 1 1 支持向量机的介绍 1 2 支持向量机的应用 2 demo数据集演示 2 1 导入函数 2 2 构建数据集拟合 2 3 预测模型及可视化 3 实例演示分类 非SVM 3 1 导入函数和数据 3 2 简单线性分类 3
  • 剑指offer Java实现 第五题

    第五题 请实现一个函数 将一个字符串中的每个空格替换成 20 例如 当字符串为We Are Happy 则经过替换之后的字符串为We 20Are 20Happy 实现代码 public static String replaceSpace
  • MSCOCO数据集格式转化成VOC数据集格式

    MSCOCO数据集格式转化成VOC数据集格式 转载请注明原出处 http blog csdn net ouyangfushu article details 79543575 作者 SyGoing QQ 2446799425 SSD目标检测
  • [springmvc学习]8、JSR 303验证及其国际化

    目录 简介 常见注解 基本使用 BindResult获取异常信息 自定义提示信息 取消属性绑定 总结 简介 JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架 它已经包含在 JavaEE 中 我们可以通过注解的方式来指
  • SFTP报错,sftp couldn‘t stat remote file:No such file or directory

    原因 使用sftp进行文件传输时 需要连接到远程服务器的root用户上去 这就导致了另一个问题 在命令行使用su命令并输入root用户密码可以切换到root用户 但是使用sftp连接root用户 会连接失败 同类型的问题也有使用xshell
  • IDE介绍

    集成开发工具 gt gt gt IDE 编码工具取代了简单的记事本工具 辅助程序员编写源代码的常用高效编写工具 类似word 我们写文档会打开word文档来编写 代码也同样需要借助工具来开发 常见的编辑工具有记事本 sublime text
  • SD HOST——(一)SD简介

    Micro SD有九个引脚 TF卡只要八个 少一个地 CLK CMD 双向口 用于发命令和接收response VDD GND GND D3 D2 D1 D0 D3 D0不一定传输的是数据 读SD内部寄存器状态也可以从D3 30输出 CMD
  • Pytorch并行训练方法-单机多卡

    简单方便的 nn DataParallel DataParallel 可以帮助我们 使用单进程控 将模型和数据加载到多个 GPU 中 控制数据在 GPU 之间的流动 协同不同 GPU 上的模型进行并行训练 细粒度的方法有 scatter g
  • 通过栈实现算术表达式的计算

    最近在看数据结构的栈 其中有一节为栈应用到算术表达式的计算 接下来我讲举例说明如何用栈去计算 如有不对的地方 请各位大神指教 1 定义操作符的优先级 作为栈顶操作符时优先级仅高于 作为栈顶操作符时优先级是最高的 和 优先级一样 但是一个作为
  • redis-cluster集群添加或删除节点以及槽重新分片

    Redis版本 5 0 0 redis 5 0 0版本后可以不用安装ruby环境 集群命令说明 redis cli cluster help Cluster Manager Commands create host1 port1 hostN
  • LLVM 介绍

    https blog csdn net weixin 38244174 article details 82705181 最近开始搞LLVM 下面我将从以下五个方面来介绍LLVM 分别是 1 LLVM是什么 2 LLVM的组成部分 3 LL
  • Python爬虫教程(非常详细)从零基础入门到精通,看完这一篇就够了

    对于绝大多数想要学习Python的朋友而言 爬虫绝对是学习Python的最好的骑手和入门方式 我当时选择Python学习 也是瞄准了Python爬虫 因为爬虫思维模式固定 编程模式也相对简单 一般在细节处理上积累一些经验都可以成功 一 正确
  • __setup宏定义

    setup宏定义 struct obs kernel param const char str int setup func char int early define initconst section init rodata defin
  • QT程序自适应窗口大小

    作为QT菜鸟的一员 总是容易遇到各种问题 然后历经千辛万苦解决它 问题 我的程序需要在ARM板 Linux系统 上跑 也需要在PC Windows上 跑 他们拥有不同大小的屏幕 在程序中布局的界面能够很好地适应窗口的大小变化 但是在UI设计
  • HTTP协议实例详解

    HTTP是一个应用层协议 由请求和响应构成 是一个标准的客户端服务模型 HTTP通常承载于TCP协议之上 有时候也承载于TLS或SSL协议层之上 这个时候 就成了常说的HTTPS 默认HTTP的端口号为80 HTTPS的端口号为443 缺点
  • Netty聊天系统(1)通过自定义协议实现客户端与服务器端通信

    1 自定义实现客户端与服务器端通信的协议 1 1 通信协议的设计 自定义的通信协议需要哪些内容 1 魔数 第一个字段一般是魔数 一般固定的几个字节 一个PNG图片的编码中有固定数量固定内容的字节 用于表示这是一个PNG图片 Java的Cla