千家信息网

套接字数据包序列化与反序列化方法是什么

发表于:2025-01-17 作者:千家信息网编辑
千家信息网最后更新 2025年01月17日,这篇文章主要介绍"套接字数据包序列化与反序列化方法是什么",在日常操作中,相信很多人在套接字数据包序列化与反序列化方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
千家信息网最后更新 2025年01月17日套接字数据包序列化与反序列化方法是什么

这篇文章主要介绍"套接字数据包序列化与反序列化方法是什么",在日常操作中,相信很多人在套接字数据包序列化与反序列化方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"套接字数据包序列化与反序列化方法是什么"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1.本文背景

经常做C/S,客户端与服务端通信基本是TCP/UDP通信,套接字用得飞起。

比如我们有一个系统,这个系统又分几个系统子模块进程:

  1. C++服务端

  2. Android 客户端

  3. iOS 客户端

  4. WPF桌面管理端 ......

几个模块之间通过TCP或者UDP通信,数据包解析与组装是常规操作,我们定义数据包格式如下:

一个数据包包含包头和包体,定义如下:

包头

序号字段名数据类型备注
1消息标识int用于标识数据包是否合法
2名称string当前消息名称,用于标识数据包类型
3版本号int当前消息版本号,允许程序中消息存在多个版本,用于版本迭代

包含这三个字段:消息标识、名称、版本号,唯一确定消息对象。

包体

序号字段名数据类型备注
1字段1数据类型字段1
2字段2数据类型字段2

包体直接定义字段信息,就像定义类属性一样。

另包头与包体中数据类型定义如下:

数据包字段类型定义

序号数据类型备注
1int4个字节的整型值
2string组成格式:字符串实际值字节长度(2个字节)+字符串实际值byte
3char单字节值
4列表组成格式:4个字节列表长度+列表实际数据值byte
5字典同上,具体后源码

其他数据类型类似,复杂数据类型使用4个字节的值字节长度+实际值byte。

给一个测试数据包

序号字段名数据类型备注
1消息标识int取值:0x4A534604
2消息名称string三国信息,取值:"ThreeCountries"
3版本号int取值:1
4编号int给三国一个编号吧,取值:1
5国名string取值:"蜀国"
6皇帝string取值:"刘备"
7大将个数int5
8大将1编号int取值:1
9大将1名字string取值:"张飞"
10大将1备注string取值:"三板斧"
11大将2编号int取值:2
12大将2名字string取值:"关羽"
13大将2备注string取值:"青龙偃月刀"
14大将3编号int取值:3
15大将3名字string取值:"赵云"
16大将3备注string取值:"很猛的"
17大将4编号int取值:4
18大将4名字string取值:"马超"
19大将4备注string取值:"强"
20大将5编号int取值:5
21大将5名字string取值:"黄忠"
22大将5备注string取值:"老当益壮"

大致理解下:

  • 前三个字段是包体:用于标识整个数据包,便于包体解析;

  • 后面的包体,简单说就是三国中的国家信息简介,前三个字段为三国中的一个国家基本信息:编号、国名、皇帝,后面是该国家大将信息列表,每个大将有编号、名称、备注等。

定义数据对象

根据数据包定义,我们可以很快定义类进行使用,不管你是C++还是Java。下面是我用C#写的对应类,用于序列化与反序列化使用:

/// /// 三国/// public class ThreeCountries{    ///     /// 获取或者设置 ID    ///     public int ID { get; set; }    ///     /// 获取或者设置 国名    ///     public string Name { get; set; }    ///     /// 获取或者设置 皇帝    ///     public string Emperor { get; set; }    ///     /// 获取或者设置 所选课程列表    ///     public List Courses { get; set; }    public override string ToString()    {        return $"三国之一{ID}:{Name}皇帝{Emperor},有 {Courses.Count}名大将";    }}/// /// 三国名将/// public class FamousGeneral{    ///     /// 获取或者设置 编号    ///     public int ID { get; set; }    ///     /// 获取或者设置 名字    ///     public string Name { get; set; }    ///     /// 获取或者设置 描述    ///     public string Memo { get; set; }    public override string ToString()    {        return $"{ID}:{Name}=>{Memo}";    }}

对于上面给的数据包你怎么序列化及反序列化?转换成数据如下,下节接着讨论

ThreeCountries shuKingdom = new ThreeCountries{    ID = 1,    Name = "蜀国",    Emperor = "刘备",    Courses = new System.Collections.Generic.List    {        new FamousGeneral{ ID=1,Name="张飞",Memo="三板斧"},        new FamousGeneral{ ID=2,Name="关羽",Memo="青龙偃月刀"},        new FamousGeneral{ ID=3,Name="赵云",Memo="很猛的"},        new FamousGeneral{ ID=3,Name="马超",Memo="强"},        new FamousGeneral{ ID=3,Name="黄忠",Memo="老当益壮"},    }};

2. 常规操作

序列化

代码太繁琐,我就写个不正规的伪代码吧

定义一个byte数组;一、写包头1、写入4字节的消息标识:0x4A534604计算消息对象名称字符串"ThreeCountries"长度,及转换字符串为byte数组2、写入2字节的bytes数组长度,写入实际的byte数组值3、写入4字节的消息版本号二、写包体4、写入4字节的大将个数循环每个大将信息,依次写入5、写入大将1编号6、写入大将1名称7、写入大奖1备注8、写入大将2编号9、写入大将3名称10、写入大奖4备注...写吐了,省略号

反序列化

不想写了,累

常规操作

定义一个序列化接口,每个网络对象实现其中的序列化与反序列化接口

public interface ISerializeInterface{  byte[] Serialize(T t);  T Deserialize(byte[] arr);}public class ThreeCountries : ISerializeInterface{  public byte[] Serialize(T t)  {    // 将上面的序列化代码写在这  }    T Deserialize(byte[] arr)  {    // 将上面的反序列化代码写在这,不好意思我没写  }}

3. 本文操作

写了半天的Demo,文章可能就写的有点水了,我估计读者也不会仔细看代码,直接去Github check项目去了,哈哈。

我还是简单说说吧,实现很简单,定义一些特性,下面红框里的代码文件:

使用很简单,在上面的数据类上加上特性,改动不多,看下面代码:

/// /// 三国/// [NetObject(Name = "ThreeCountries", Version = 1)]public class ThreeCountries{    ///     /// 获取或者设置 ID    ///     [NetObjectProperty(ID = 1)]    public int ID { get; set; }    ///     /// 获取或者设置 国名    ///     [NetObjectProperty(ID = 2)]    public string Name { get; set; }    ///     /// 获取或者设置 皇帝    ///     [NetObjectProperty(ID = 3)]    public string Emperor { get; set; }    ///     /// 获取或者设置 所选课程列表    ///     [NetObjectProperty(ID = 4)]    public List Courses { get; set; }    public static NetObjectAttribute CurrentObject = null;    static ThreeCountries()    {        CurrentObject = NetObjectSerializeHelper.GetAttribute(default(ThreeCountries));    }    public override string ToString()    {        return $"三国之一{ID}:{Name}皇帝{Emperor},有 {Courses.Count}名大将";    }}/// /// 三国名将/// public class FamousGeneral{    ///     /// 获取或者设置 编号    ///     [NetObjectProperty(ID = 1)]    public int ID { get; set; }    ///     /// 获取或者设置 名字    ///     [NetObjectProperty(ID = 2)]    public string Name { get; set; }    ///     /// 获取或者设置 描述    ///     [NetObjectProperty(ID = 3)]    public string Memo { get; set; }    public override string ToString()    {        return $"{ID}:{Name}=>{Memo}";    }}

仔细看的话,只在外层类(ThreeCountries)上加了NetObject特性,和属性上加了NetObjectProperty特性,分别标识消息名称、版本号及每个属性的序列化与反序列化顺序即可,类中使用的子对象Courses属性,也只需要加属性特性即可,如上。

下面添加单元测试,并且测试通过:

到此,关于"套接字数据包序列化与反序列化方法是什么"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

数据 大将 序列 备注 字段 消息 字节 类型 三国 名称 标识 版本 代码 名字 信息 皇帝 套接字 方法 实际 对象 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 北京最好网络安全培训机构 云南省公安厅网络安全处处长 计算机网络技术证书有哪些 信息网络技术与应用专业 人工智能在网络安全领域论论文 服务器机房 安全责任制度 智能互联网科技平台 济南易途网络技术有限公司 全国网络安全状况调查报告 去车企软件开发 宿豫区环保网络技术联系方式 数据库程序设计报考难不难 服务器做虚拟化能混插内存吗 魔兽世界怀旧服服务器不断刷怪 服务器管理员永久怎么弄 虎丘区一站式网络技术哪家好 飞机导航数据库的性能 如何将sql数据库导入虚拟主机 数据库表怎么保证一对一 公安局加强网络安全监管工作 idm下载提示服务器关闭 工商局服务器异常 项目网络安全情况分析 qt客户端发送文件存进数据库 服务器上网卡速率 什么不是sql数据库对象 计算机网络安全就职 点餐服务系统数据库 广州前端软件开发机构 确保奥运会网络安全的具体措施
0