/// <summary>
        /// Serializes the network frame into datagrams.
        /// </summary>
        /// <param name="networkFrame">Network frame.</param>
        /// <returns>List of datagrams.</returns>
        /// <exception cref="ArgumentException">
        /// The <paramref name="networkFrame"/> is invalid.
        /// </exception>
        public IEnumerable <byte[]> Serialize(NetworkFrame networkFrame)
        {
            if (!ValidateFrame(networkFrame))
            {
                throw new ArgumentException("The network frame is invalid", nameof(networkFrame));
            }

            int index = 0, packetNumber = 0, frameSize = networkFrame.DataSegments.Sum(e => e.Count);
            int segment = 0, segmentOffset = 0;

            var packets   = new List <byte[]>();
            var taskBytes = Encoding.UTF8.GetBytes(networkFrame.Task);
            var flowBytes = Encoding.UTF8.GetBytes(networkFrame.Flow);

            Array.Resize(ref taskBytes, TaskIdSize);
            Array.Resize(ref flowBytes, FlowIdSize);

            while (index < frameSize)
            {
                var dataSize = Math.Min(PacketDataMaxSize, frameSize - index);
                var packet   = new byte[PacketHeaderSize + dataSize];
                using var stream = new MemoryStream(packet);
                using var writer = new EndianBinaryWriter(stream);

                writer.Write(ProtocolVersion);
                writer.Write((ushort)0);
                writer.Write((ushort)packet.Length);
                writer.Write((ushort)packetNumber++);
                writer.Write((uint)index);
                writer.Write(networkFrame.Id);
                writer.Write((uint)frameSize);
                writer.Write(networkFrame.Number);
                writer.Write(networkFrame.Interpretation);
                writer.Write(taskBytes);
                writer.Write(flowBytes);

                while (segment < networkFrame.DataSegments.Length && dataSize > 0)
                {
                    while (segmentOffset >= networkFrame.DataSegments[segment].Count)
                    {
                        ++segment;
                        segmentOffset = 0;
                    }

                    var copySize = Math.Min(dataSize, networkFrame.DataSegments[segment].Count - segmentOffset);
                    writer.Write(networkFrame.DataSegments[segment].Slice(segmentOffset, copySize));

                    segmentOffset += copySize;
                    index         += copySize;
                    dataSize      -= copySize;
                }

                writer.Seek(1, SeekOrigin.Begin);
                writer.Write(Checksum.Crc16(packet));
                packets.Add(packet);
            }

            return(packets);
        }
示例#2
0
        public int TestCrc16(string asciiString)
        {
            var bytes = Encoding.ASCII.GetBytes(asciiString);

            return(Checksum.Crc16(bytes));
        }