JD2022-TU1/main/tools/framework/JD.Remoting/Details/PacketBuilder.cs

60 lines
No EOL
2.3 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
namespace JD.Remoting.Details
{
/// <summary>
/// Builds packets from a message (the inverse of MessageBuilder).
/// </summary>
internal class PacketBuilder
{
public const int MaximumTcpPacketBodySize = 8156;
public static IEnumerable<byte[]> BuildPackets(MessageHeader messageHeader, IBlob messageContent)
{
List<byte[]> result = new List<byte[]>();
byte[] messageHeaderContent = MessageHeaderToBytes(messageHeader);
messageContent.Seek(0, SeekOrigin.Begin);
int totalSize = messageHeaderContent.Length + (int)messageContent.Length;
int packetCount = (int)Math.Ceiling((double)totalSize / MaximumTcpPacketBodySize);
uint messageId = PacketHeader.NextMessageId;
for (int i = 0; i < packetCount; i++)
{
var header = new PacketHeader
{
BodySize = (uint)(i == packetCount - 1 ? totalSize % MaximumTcpPacketBodySize : MaximumTcpPacketBodySize),
GlobalBodySize = (uint)totalSize,
Index = (uint)i,
MaxIndex = (uint)(packetCount - 1),
MessageId = messageId
};
var packetContent = new byte[PacketHeader.HeaderSize + header.BodySize];
var writeStream = new MemoryStream(packetContent);
header.Write(writeStream);
if (i == 0)
{
writeStream.Write(messageHeaderContent, 0, messageHeaderContent.Length);
messageContent.ExtractBytes(packetContent, (int)writeStream.Position, (int)header.BodySize - messageHeaderContent.Length);
}
else
{
messageContent.ExtractBytes(packetContent, (int)writeStream.Position, (int)header.BodySize);
}
result.Add(packetContent);
}
return result;
}
private static byte[] MessageHeaderToBytes(MessageHeader header)
{
var headerContent = new MemoryStream();
header.Write(headerContent);
return headerContent.ToArray();
}
}
}