程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Socket開發探秘--基於Json格式的數據協議收發

Socket開發探秘--基於Json格式的數據協議收發

編輯:關於.NET

前面發表過兩篇隨筆:《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()生成接受到的數據內容,查看具體的 內容,得到的效果如下所示。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved