public void TestWriteRead() { PackageHead target = new PackageHead(); PackageHead other = new PackageHead(); byte[] temp = new byte[PackageHead.SizeOf]; target.Flags = byte.MinValue; target.MessageLength = ushort.MinValue; target.WriteTo(temp, 0); other.ReadFrom(temp, 0); Assert.AreEqual(target, other); target.Flags = (PackageHeadFlags)byte.MaxValue; target.MessageLength = ushort.MaxValue; target.WriteTo(temp, 0); other.ReadFrom(temp, 0); Assert.AreEqual(target, other); Random random = new Random(); int index = random.Next(100); temp = new byte[PackageHead.SizeOf + 100]; target.Flags = (PackageHeadFlags)12; target.MessageLength = 16; target.WriteTo(temp, index); other.ReadFrom(temp, index); Assert.AreEqual(target, other); }
/// <summary> /// 序列化要发送的message /// </summary> public TcpSession.SendingHandler CreateSendingHandler() { TcpSession.SendingHandler handler = (messages, stream) => { foreach (var message in messages) { // 保留包头空间 var headerPosition = stream.Position; stream.SetLength(stream.Length + PackageHead.SizeOf); stream.Position += PackageHead.SizeOf; // 序列化消息 serializer.Serialize(message, stream); PackageHead header = new PackageHead(); var length = stream.Length - (headerPosition + PackageHead.SizeOf); // 超大包 if (length > ushort.MaxValue) { // 写入第一个包的包头 header.Flags |= PackageHeadFlags.Partial; header.MessageLength = ushort.MaxValue; header.WriteTo(stream.GetBuffer(), (int)headerPosition); length -= ushort.MaxValue; // 从第一个包末尾截断,把剩余数据拷到临时缓冲中 var keptSize = headerPosition + ushort.MaxValue + PackageHead.SizeOf; var dataLeft = new byte[stream.Length - keptSize]; var offset = 0; stream.Position = keptSize; stream.Read(dataLeft, 0, dataLeft.Length); stream.Position = keptSize; stream.SetLength(keptSize); // 从临时缓冲中把剩余数据加上包头写入 while (length > 0) { ushort truncateLength = ushort.MaxValue; // 最后的部分 if (length <= ushort.MaxValue) { truncateLength = (ushort)length; header.Flags &= ~PackageHeadFlags.Partial; } header.MessageLength = truncateLength; header.WriteTo(stream); stream.Write(dataLeft, offset, truncateLength); offset += truncateLength; length -= truncateLength; } Debug.Assert(offset == dataLeft.Length); } else // 普通大小的包 { // 写入包头 header.MessageLength = (ushort)length; header.WriteTo(stream.GetBuffer(), (int)headerPosition); } } }; return handler; }