关于网络通信中数据包的组包问题

    网络通信中,通常需要对数据包进行组包操作,即是给指定的数据包加上起始标识、长度等附加信息。本人在开发流媒体项目过程中,就面临着这样一个问题。其实这类问题并不难解决,之所以在这里提出来,主要目的是为了对近期开发过程中遇到的一些问题记录下来,以便于后期项目的回顾。

    在本人所面临的实际项目中,首先需要读取音视频文件数据块,然后对读取的音视频数据块进行组包并放入发送队列,通过Socket发送给客户端。文件读取采用了异步读取方式,对每一个音视频数据块,加上了数据包头部标识和包序列号。

    为顺利达到这一目的,本人写了两个静态方法,一个为CreateDataPacket,一个为ConvertLongToByteArray,其中CreateDataPacket方法根据自定义的数据包规则进行组包操作,其代码示例如下:
/// <summary>
        /// 创建数据包,数据包组成规则如下:
        /// <para>[HeaderCode][SequenceLength][Sequence][DataLengthLength][DataLength][Data]</para>
        /// </summary>
        /// <param name="headerCode">包头部标识</param>
        /// <param name="sequence">包序列号</param>
        /// <param name="Data">数据块</param>
        /// <returns>数据包</returns>
        public static byte[] CreateDataPacket(byte headerCode, long sequence, byte[] data)
        {
            byte[] bytArrHeader = new byte[1] { headerCode};
            byte[] bytArrSequence = ConvertLongToByteArray(sequence);
            byte[] bytArrSequenceLength = new byte[1] { (byte)bytArrSequence.Length};
            byte[] bytArrDataLength = ConvertLongToByteArray((long)data.Length);
            byte[] bytArrDataLengthLength = new byte[1] { (byte)bytArrDataLength .Length};

            int intPrefixLength = bytArrHeader.Length + bytArrSequenceLength.Length + bytArrSequence.Length + bytArrDataLengthLength.Length + bytArrDataLength.Length;

            byte[] newData = new byte[intPrefixLength + data.Length];

            try
            {
                // copy headerCode
                bytArrHeader.CopyTo(newData, 0);
                // copy sequence length
                bytArrSequenceLength.CopyTo(newData, bytArrHeader.Length);
                // copy sequence
                bytArrSequence.CopyTo(newData, bytArrHeader.Length + bytArrSequenceLength.Length);
                // copy data length's length
                bytArrDataLengthLength.CopyTo(newData, bytArrHeader.Length + bytArrSequenceLength.Length + bytArrSequence.Length);
                // copy data length
                bytArrDataLength.CopyTo(newData, bytArrHeader.Length + bytArrSequenceLength.Length +bytArrSequence.Length +bytArrDataLengthLength.Length);
                // copy data
                data.CopyTo(newData, intPrefixLength);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return newData;
        }
   

    另一个方法ConvertLongToByteArray用于配合完成数据包的组包工作,其目的是将长整型数值转换为字节数组,其代码示例如下:
public static byte[] ConvertLongToByteArray(long number)
    {
        List<byte> bytes = new List<byte>();
        while (number / 256 > 0)
        {
            bytes.Add((byte)(number % 256));
            number /= 256;
        }
        bytes.Add((byte)number);
        byte[] arrBytes = new byte[bytes.Count];
        bytes.CopyTo(arrBytes);
        return arrBytes;
    }

    在上述的代码中通过使用CopyTo方法将当前的元素复制到指定的Array中去。总的来看,上述这种组包方法还是相当简单的,关键是要定义好数据包的规则,然后根据这个规则去处理就OK了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踏雪无痕大黄蜂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值