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

简介:

前面发表过两篇随笔:《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格式的数据协议收发,如需转载请自行联系原博主。



 

目录
相关文章
|
9月前
|
JSON API 数据格式
淘宝拍立淘按图搜索API系列,json数据返回
淘宝拍立淘按图搜索API系列通过图像识别技术实现商品搜索功能,调用后返回的JSON数据包含商品标题、图片链接、价格、销量、相似度评分等核心字段,支持分页和详细商品信息展示。以下是该API接口返回的JSON数据示例及详细解析:
|
9月前
|
JSON 算法 API
Python采集淘宝商品评论API接口及JSON数据返回全程指南
Python采集淘宝商品评论API接口及JSON数据返回全程指南
|
9月前
|
JSON API 数据安全/隐私保护
Python采集淘宝拍立淘按图搜索API接口及JSON数据返回全流程指南
通过以上流程,可实现淘宝拍立淘按图搜索的完整调用链路,并获取结构化的JSON商品数据,支撑电商比价、智能推荐等业务场景。
|
9月前
|
JSON 中间件 Java
【GoGin】(3)Gin的数据渲染和中间件的使用:数据渲染、返回JSON、浅.JSON()源码、中间件、Next()方法
我们在正常注册中间件时,会打断原有的运行流程,但是你可以在中间件函数内部添加Next()方法,这样可以让原有的运行流程继续执行,当原有的运行流程结束后再回来执行中间件内部的内容。​ c.Writer.WriteHeaderNow()还会写入文本流中。可以看到使用next后,正常执行流程中并没有获得到中间件设置的值。接口还提供了一个可以修改ContentType的方法。判断了传入的状态码是否符合正确的状态码,并返回。在内部封装时,只是标注了不同的render类型。再看一下其他返回的类型;
401 3
|
9月前
|
JSON Java Go
【GoGin】(2)数据解析和绑定:结构体分析,包括JSON解析、form解析、URL解析,区分绑定的Bind方法
bind或bindXXX函数(后文中我们统一都叫bind函数)的作用就是将,以方便后续业务逻辑的处理。
477 3
|
10月前
|
JSON API 数据安全/隐私保护
Python采集淘宝评论API接口及JSON数据返回全流程指南
Python采集淘宝评论API接口及JSON数据返回全流程指南
|
10月前
|
JSON 自然语言处理 监控
淘宝关键词搜索与商品详情API接口(JSON数据返回)
通过商品ID(num_iid)获取商品全量信息,包括SKU规格、库存、促销活动、卖家信息、详情页HTML等。
|
网络协议 开发者 Python
深度探索Python Socket编程:从理论到实践,进阶篇带你领略网络编程的魅力!
【7月更文挑战第25天】在网络编程中, Python Socket编程因灵活性强而广受青睐。本文采用问答形式深入探讨其进阶技巧。**问题一**: Socket编程基于TCP/IP,通过创建Socket对象实现通信,支持客户端和服务器间的数据交换。**问题二**: 提升并发处理能力的方法包括多线程(适用于I/O密集型任务)、多进程(绕过GIL限制)和异步IO(asyncio)。**问题三**: 提供了一个使用asyncio库实现的异步Socket服务器示例,展示如何接收及响应客户端消息。通过这些内容,希望能激发读者对网络编程的兴趣并引导进一步探索。
386 4
|
开发者 Python
Python Socket编程:不只是基础,更有进阶秘籍,让你的网络应用飞起来!
【7月更文挑战第25天】在网络应用蓬勃发展的数字时代,Python凭借其简洁的语法和强大的库支持成为开发高效应用的首选。本文通过实时聊天室案例,介绍了Python Socket编程的基础与进阶技巧,包括服务器与客户端的建立、数据交换等基础篇内容,以及使用多线程和异步IO提升性能的进阶篇。基础示例展示了服务器端监听连接请求、接收转发消息,客户端连接服务器并收发消息的过程。进阶部分讨论了如何利用Python的`threading`模块和`asyncio`库来处理多客户端连接,提高应用的并发处理能力和响应速度。掌握这些技能,能使开发者在网络编程领域更加游刃有余,构建出高性能的应用程序。
254 3
|
网络协议 Python
网络世界的建筑师:Python Socket编程基础与进阶,构建你的网络帝国!
【7月更文挑战第26天】在网络的数字宇宙中,Python Socket编程是开启网络世界大门的钥匙。本指南将引领你从基础到实战,成为网络世界的建筑师。
338 2