/// <summary>
        /// 对块进行切片
        /// </summary>
        /// <param name="buffer">块数据</param>
        /// <param name="identity">文件标识</param>
        /// <returns></returns>
        public List <byte[]> BlockSlice(byte[] buffer, ushort identity)
        {
            List <byte[]> result     = new List <byte[]>();
            ushort        sliceCount = (ushort)(buffer.Length / SlicePackageSize);

            if (buffer.Length % SlicePackageSize > 0)
            {
                sliceCount++;
            }

            for (ushort i = 1; i <= sliceCount; i++)
            {
                var tmp = buffer.Length - (i - 1) * SlicePackageSize;
                var blockSlicePackage = new UdpPackage()
                {
                    PackageIdentity    = identity,
                    PackageOpCode      = (byte)OpCode.Message,
                    PackageBlockSerial = BlockSerial,
                    PackageSliceSerial = i,
                    PackageSliceCount  = sliceCount,
                    PackageBody        = buffer.Skip((i - 1) * SlicePackageSize)
                                         .Take(tmp < SlicePackageSize ? tmp : SlicePackageSize).ToArray()
                };

                result.Add(blockSlicePackage.ToBytes());
            }

            NextBlock();

            return(result);
        }
        /// <summary>
        /// 收集块切片
        /// </summary>
        /// <param name="buffer">切片</param>
        /// <param name="lostSlices">丢失的切片序号</param>
        /// <returns>切片组装状态</returns>
        public bool SlicePackageConcat(byte[] buffer, out ushort[] lostSlices, out bool isEnd)
        {
            isEnd      = false;
            lostSlices = null;
            if (buffer.Length == 0)
            {
                return(false);
            }

            var package = new UdpPackage().BytesToUdpPackage(buffer);

            switch ((OpCode)package.PackageOpCode)
            {
            case OpCode.Start:
                FileName = Encoding.UTF8.GetString(package.PackageBody);
                return(false);

            case OpCode.End:
                return(IntegrityChecks(Convert.ToUInt16(Encoding.UTF8.GetString(package.PackageBody)), out lostSlices, out isEnd));

            case OpCode.Notice:
                BlockNum = Convert.ToInt32(Encoding.UTF8.GetString(package.PackageBody));
                return(false);
            }

            BlockSlicePackages.Add(package);

            // 块完整性检查
            if (package.PackageSliceCount ==
                BlockSlicePackages.Count(x => x.PackageBlockSerial == package.PackageBlockSerial))
            {
                return(true);
            }

            return(false);
        }