前面发表过两篇随笔:《Socket开发探秘--基类及公共类的定义》和《Socket开发探秘--数据封包和拆包》,介绍了Socket方面的开发。本文继续探讨使用Json格式来作为Socket收发协议方面的技术问题。

前面说到,收到的Socket数据经过粗略的解析后,就是PreData类型的数据,这个是通用的数据格式,我们需要进一步处理才能转化为所能认识的数据对象(实体类对象),同样,我们发送数据的时候,内容部分肯定是按照一定协议规则串联起来的数据,那么我们就需要把实体转化为发送的数据格式。综上所述,我们通过实体类,必须实现数据的发送和读取的转换。

由于数据的封包拆包是一个繁琐的过程,代码重复性比较多,而且也容易出错。前面介绍过设计一个基类,我们把所有对数据的拆包和封包,利用反射机制,减少我们的代码量,提高代码的优雅性。 但是后来有人建议,可能使用Json格式的数据内容可能更好,确实,如果是采用以|分割符号的内容,有一个缺点,就是数据内容比较难懂(有时候我们还是需要分析数据包的),Json会更易读一些。 另外,使用Json可以脱离字段顺序的关系,可以向后兼容一些历史的协议,例如首次定义的协议有字段A、B,后来服务器升级,升级增加支持C、D,旧的客户端可以和新的客户端并存,增加了兼容性。
因此我在此基础上优化一下代码,使其支持Json格式的数据发送,其实由于之前的代码封装的还算比较好,因此修改为Json格式的协议内容,只需要修改BaseEntity中几行代码即可实现,下面贴出修改代码的前后对比(注释掉的代码是原来的代码):

代码

    public class BaseEntity
    {
        protected string HeaderKey;

public BaseEntity()
        {
        }

/// <summary>
        /// 转换Socket接收到的信息为对象信息
        /// </summary>
        /// <param name="data">Socket接收到的信息</param>
        public BaseEntity(string data)
        {
            #region 普通按顺序构造的代码
            //string[] dataArray = null;
            //dataArray = NetStringUtil.UnPack(data);
            //if (dataArray != null && dataArray.Length > 0)
            //{
            //    int i = 0;
            //    FieldInfo[] fieldArray = ReflectionUtil.GetFields(this);
            //    if (fieldArray == null || dataArray.Length != fieldArray.Length)
            //    {
            //        throw new ArgumentException("收到的信息和字段信息不一致");
            //    }

//    if (fieldArray != null)
            //    {
            //        foreach (FieldInfo info in fieldArray)
            //        {
            //            string strValue = dataArray[i++];
            //            ReflectionUtil.SetField(this, info.Name, strValue);
            //        }
            //    }
            //} 
            #endregion

//Json格式转换后的内容,肯定是小于或者等于实体类的内容
            //因为对象要兼容历史的Json内容,通过反射以最小的成员来赋值
            BaseEntity obj = JsonTools.JsonToObject(data, this.GetType()) as BaseEntity;
            if (obj != null)
            {
                FieldInfo[] fieldArray = ReflectionUtil.GetFields(obj);
                foreach (FieldInfo info in fieldArray)
                {
                    object value = ReflectionUtil.GetField(obj, info.Name);
                    ReflectionUtil.SetField(this, info.Name, value);
                }                
            }
        }

/// <summary>
        /// 转换对象为Socket发送格式的字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string data = "";

#region 普通按顺序构造的代码
            //FieldInfo[] fieldArray = ReflectionUtil.GetFields(this);
            //StringBuilder sb = new StringBuilder();
            //if (fieldArray != null)
            //{
            //    foreach (FieldInfo info in fieldArray)
            //    {
            //        sb.Append(ReflectionUtil.GetField(this, info.Name));
            //        sb.Append("|");
            //    }
            //}
            //data = sb.ToString().Trim('|'); 
            #endregion

#region 按Json格式构造的代码

data = JsonTools.ObjectToJson(this);

#endregion

if (string.IsNullOrEmpty(HeaderKey))
            {
                throw new ArgumentNullException("DataTypeKey", "实体类未指定协议类型");
            }
            data = NetStringUtil.PackSend(HeaderKey, data);
            return data;
        }
    }

JsonTools是一个Json的辅助类,负责Json内容的解析的,由于我的项目是采用C#2.0的,因此Json操作采用了Newtonsoft.Json.dll类库,如果是C#3.5的,采用系统内置类库就可以了。

代码

    /// <summary>
    /// Json处理类
    /// </summary>
    public class JsonTools
    {
        /// <summary>
        /// 从一个对象信息生成Json串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ObjectToJson(object obj)
        {
            return JavaScriptConvert.SerializeObject(obj);
        }

/// <summary>
        /// 从一个Json串生成对象信息
        /// </summary>
        /// <param name="jsonString"></param>
        /// <param name="objType"></param>
        /// <returns></returns>
        public static object JsonToObject(string jsonString, Type objType)
        {
            return JavaScriptConvert.DeserializeObject(jsonString, objType);
        }

}

这样就可以实现Json格式内容的发送和接受了。

使用测试客户端对数据进行测试,并调用ToString()生成接受到的数据内容,查看具体的内容,得到的效果如下所示。

Socket开发探秘--基于Json格式的数据协议收发相关推荐

  1. 如何在Django中接收JSON格式的数据

    Django做了大量工作简化我们的Web开发工作, 这其中当然也包括接收来自客户端的数据这一普遍需求. 大部分时候,从客户端传入的数据主要是FORM的POST数据,和来自URL的GET数据, 在Dja ...

  2. java异步请求显示数据格式_JSON(四)——异步请求中前后端使用Json格式的数据进行交互...

    json格式的数据广泛应用于异步请求中前后端的数据交互,本文主要介绍几种使用场景和使用方法. 一,json格式字符串 functionsentAjax(){ $.ajax({ type:'POST', ...

  3. flex 解析json文件_使用 Python 处理 JSON 格式的数据 | Linux 中国

    如果你不希望从头开始创造一种数据格式来存放数据,JSON 是一个很好的选择.如果你对 Python 有所了解,就更加事半功倍了.下面就来介绍一下如何使用 Python 处理 JSON 数据.-- Se ...

  4. html如何查看json数据,浏览器如何查看json格式的数据?查看方法分享

    用户在使用浏览器的时候不仅仅只是搜索自己想要的内容,在项目开发的时候就需要用户查看更多接口的数据,查看的数据就会比较乱,用户可以使用手机在平台上快速使用,马上就可以帮助用户想要的数据,那么要如何才能查 ...

  5. Python爬虫 scrapy框架 爬取智联招聘,并把数据存入数据库,存为json格式的数据

    First:创建项目:执行下面三句命令: 1. scrapy startproject zhilianzhaopin2. cd zhilianzhaopin3.scrapy genspider zhi ...

  6. 调用python脚本并传递参数json格式_使用 Python 处理 JSON 格式的数据

    如果你不希望从头开始创造一种数据格式来存放数据,JSON 是一个很好的选择.如果你对 Python 有所了解,就更加事半功倍了.下面就来介绍一下如何使用 Python 处理 JSON 数据. JSON ...

  7. 在python中使用json格式存储数据

    在python中使用json格式存储数据 代码如下: import jsonlist1 = [{'A': [1, 2, 3, 4, 5, 6], 'B': [3, 4, 5, 6, 7]},{'C': ...

  8. $.ajax返回的JSON格式的数据后无法执行success的解决方法

    $.ajax返回的JSON格式的数据后无法执行success的解决方法 参考文章: (1)$.ajax返回的JSON格式的数据后无法执行success的解决方法 (2)https://www.cnbl ...

  9. Jquery 将后台返回的字符串转换成Json格式的数据

    //code by:博客园-曹永思 第一步:将DataTable转换成 Json格式的数据 方法 一 View Code /// <summary>/// DataTable转成Json格 ...

最新文章

  1. Linux下JDK环境的配置
  2. mybatis入门(三)之Mapper XML 文件
  3. 前端学习(554):node实现登录和注册第二部分代码
  4. 百度SEO Cloud-Platform(后台管理系统) v3.1.0
  5. 中内连和外联的去区别_外联请客丨第一百七十四期:鱼来了铁板烧请你吃铁板烤鱼和香辣牛蛙虾!...
  6. navicat for MySQL连接本地数据库时报1045错误的解决方法
  7. 机器学习——卷积神经网络(CNN)
  8. AI CC呼叫中心源码
  9. C++Windows连点器制作
  10. [无视][mark]退役记
  11. html外链视频,WordPress文章内容中插入外链视频的通用iframe方法
  12. Unity中Vive Controller手柄模型渲染流程和模型替换
  13. 酷柚易汛进销存-如何新增付款单?
  14. linux系统查看dns缓存,如何清空linux的DNS缓存
  15. RPA风潮席卷全行业,本土厂商如何把握未来?
  16. Netgear R6220刷潘多拉盒子后的WIFI配置,20HZ频宽下载速度达9M
  17. Linux 下使用 sem_t 有名信号量的注意事项
  18. 艾棣维欣联合INOVIO开展新冠DNA疫苗全球III期临床试验;陆道培医疗与辉瑞达成合作 | 医药健闻...
  19. 【软件推荐】第1节:Micorsoft To Do
  20. 经验——从普通一本跨考东北大学计算机研究生

热门文章

  1. 32 位的有符号整数_「js基础」JavaScript逻辑和位运算符归纳
  2. LNMP与LAMP的工作原理
  3. FreeRTOS(五)——heap文件解析
  4. 51nod1574排列转换
  5. JMeter工作基本原理
  6. silverlight实现图片局部放大效果
  7. bootstrap3 - 分页
  8. c#自带压缩类实现数据库表导出到CSV压缩文件的方法
  9. IE下jquery的fadeIn与fadeOut方法失效的BUG
  10. Office 365身份认证管理-安装并配置活动目录同步