在网络的数据传输中,要将需要传输的数据转换为二进制数据后传输,才能被服务端正常的接收,socket传输中,接收到的数据都会被放入byte[]中存放,所以在数据发送前,对二进制的数组进行有规律的排序,才能在服务端以相同的方式进行读取,我理解中的协议,便是这个排列的顺序。

1.数据转换成二进制

Encoding.XXX.GetBytes(Str)
using (MemoryStream memStream=new MemoryStream())
{
      memStream.WriteByte(Str);
}
using (MemoryStream memStream=new MemoryStream())
{
      memStream.ReadByte(bytes);
}  

以上两种方式都可以将字符串转换成二进制,但第一种显然不大容易解析和读取,因为当我们需要传递一个数据模型的时候,转换成二进制后解析的时候会很费力气,且方法很难重用,所以当数据传输的类型、数量复杂的时候 第二种方式是不错的选择。

2.协议

所谓协议,就是在传输的时候按照固定的顺序使用MemoryStream类将对象write成byte[],然后读取的时候也使用该类按照相同的顺序解析。

协议定义代码

定义了一个公用的二进制和对象之间的转换类BytesHelper

public class BytesHelper<T>
{

    /// <summary>
    /// 将类对象转换为byte数组
    /// </summary>
    /// <param name="t"></param>
    /// <returns></returns>
    public static byte[] ToBytes(T t)
    {
        byte[] buff;
        using (MemoryStream ms = new MemoryStream())
        {
            IFormatter iFormatter = new BinaryFormatter();
            iFormatter.Serialize(ms, t);
            buff = ms.GetBuffer();
        }
        return buff;
    }

    /// <summary>
    /// 将byte数组转化为对象
    /// </summary>
    /// <param name="buff"></param>
    /// <returns></returns>
    public static T ToModel(byte[] buff)
    {
        T obj;
        using (MemoryStream ms = new MemoryStream(buff))
        {
            IFormatter iFormatter = new BinaryFormatter();
            obj = (T)iFormatter.Deserialize(ms);
        }
        return obj;
    }
}

这样就可以通过对象和二进制之间的转换来使用固定的协议类型了,而协议也可以写作实体形式进行传递、解析。下面是协议的简单写法:

public interface IProto<T>
{
    ushort ProtoCode { get; }
    byte[] ToArray();
    T GetProto(byte[] buffer);
}
public struct MyProto : IProto<MyProto>
{
    public ushort ProtoCode { get { return 2001; } }

    public int uid; 

    public byte[] GetByte()
    {
        using (MemoryStream ms = new MemoryStream())
        {
            ms.WriteUShort(ProtoCode);
            ms.WriteInt(uid);
            return ms.ToArray();
        }
    }

    public MyProto GetProto(byte[] buffer)
    {
        MyProto proto = new MyProto();
        using (MemoryStream ms = new MemoryStream(buffer))
        {
            proto.uid = ms.ReadInt();
        }
        return proto;
    }
}

最新文章

  1. 管理者与下属谈话的技巧及注意点[持续更新ing]
  2. 重写TextField Rect 改变显示位置
  3. salesforce 零基础学习(二十四)解析csv格式内容
  4. Linux设备驱动之中断支持及中断分层
  5. python基础——装饰器
  6. iOS开发——iOS学习路线
  7. C# Winform 文件编码批量转换工具
  8. Eddy&#39;s digital Roots
  9. Asp.Net MVC 模型验证详解-实现客户端、服务端双重验证
  10. 教你如何拔取百度地图POI兴趣点
  11. 利用 img 和 script 发送跨域请求
  12. 教你50招提升ASP.NET性能(二十三):StringBuilder不适用于所有字符串连接的场景;String.Join可能是
  13. Javaweb统计在线人数的小栗子
  14. ELK系列~对fluentd参数的理解
  15. [转]XModem协议
  16. [NewLife.XCode]对象字典缓存(百万军中取敌首级)
  17. ASP.NET新增数据返回自增ID
  18. DNSLog注入笔记
  19. 【JUC】JDK1.8源码分析之ReentrantReadWriteLock
  20. maven-java包管理工具-01

热门文章

  1. 安装solaris_11.2与windows双系统(VM10模拟实现)(二)
  2. 自制DTU
  3. 如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
  4. 使用mod_cluster进行apache httpd server和jboss eap 6.1集群配置
  5. 《Qt编程的艺术》——8.2 显示目录层次
  6. DOM注意事项(八):JavaScript操作环境和垃圾收集
  7. hdu 5256 序列变换 (LIS变形)
  8. Python中文字符的理解:str()、repr()、print
  9. Mac &#160;任何选项没有了怎么办?
  10. JavaScript 的DOM操作