前文介紹 Socket 基類、封包拆包。本文優化協議內容採用 JSON 格式,優勢:
原版按順序用 | 分隔,現改用 Newtonsoft.Json (C# 2.0) 或內建 JavaScriptSerializer (3.5+)。
public class BaseEntity {
protected string HeaderKey;
public BaseEntity() {}
// 解構:Socket 收到字串 → 物件
public BaseEntity(string data) {
#region 舊版按順序解析 (註解)
// string[] arr = NetStringUtil.UnPack(data);
// if (arr != null && arr.Length > 0) {
// int i=0; var fields = ReflectionUtil.GetFields(this);
// if (fields==null || arr.Length!=fields.Length) throw new ArgumentException("欄位不符");
// foreach (var f in fields) ReflectionUtil.SetField(this, f.Name, arr[i++]);
// }
#endregion
// JSON 反序列化,相容歷史欄位 (以最小成員賦值)
var obj = JsonTools.JsonToObject(data, this.GetType()) as BaseEntity;
if (obj != null) {
foreach (var f in ReflectionUtil.GetFields(obj)) {
var val = ReflectionUtil.GetField(obj, f.Name);
ReflectionUtil.SetField(this, f.Name, val);
}
}
}
// 序列化:物件 → Socket 發送字串
public override string ToString() {
string data;
#region 舊版按順序組裝 (註解)
// var sb = new StringBuilder();
// foreach (var f in ReflectionUtil.GetFields(this)) { sb.Append(ReflectionUtil.GetField(this,f.Name)); sb.Append("|"); }
// data = sb.ToString().Trim('|');
#endregion
data = JsonTools.ObjectToJson(this); // JSON 序列化
if (string.IsNullOrEmpty(HeaderKey)) throw new ArgumentNullException("DataTypeKey", "未指定協議類型");
return NetStringUtil.PackSend(HeaderKey, data);
}
}
public class JsonTools {
public static string ObjectToJson(object obj) => JavaScriptConvert.SerializeObject(obj);
public static object JsonToObject(string json, Type t) => JavaScriptConvert.DeserializeObject(json, t);
}
客戶端測試生成封包內容:


僅修改 BaseEntity 核心幾行即可無縫切換至 JSON 協議,展現良好封裝彈性。