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 /// messageHandler需要保证线程安全 /// </summary> public TcpSession.ReceivedHandler CreateReceivedHandler(TcpSession session, Action<TcpSession, object> messageHandler) { bool isInitialized = false; bool isReadingHeader = true; bool isPartial = false; var partialStream = new MemoryStream(); TcpSession.ReceivedHandler handler = stream => { if (!isInitialized) { Debug.Assert(stream.Length == 0 && stream.Position == 0); isInitialized = true; return PackageHead.SizeOf; } if (isReadingHeader) { PackageHead header = new PackageHead(); header.ReadFrom(stream.GetBuffer(), (int)stream.Position); isReadingHeader = false; isPartial = ((header.Flags & PackageHeadFlags.Partial) == PackageHeadFlags.Partial); return header.MessageLength; } else { if (isPartial) // 超大包未接收完全 { // 在临时缓冲中拼包 stream.WriteTo(partialStream); } else if (partialStream.Length != 0) // 超大包最后一个分包 { // 拼包然后反序列化 stream.WriteTo(partialStream); object message = null; try { message = this.serializer.Deserialize(partialStream.GetBuffer(), 0, (int)partialStream.Length); } catch (Exception e) { OnMessageDeserializeFailed(e); } if (message != null) messageHandler(session, message); partialStream.Position = 0; partialStream.SetLength(0); } else // 普通大小的包 { // 直接反序列化 object message = null; try { message = this.serializer.Deserialize(stream.GetBuffer(), (int)stream.Position, (int)stream.Length); } catch (Exception e) { OnMessageDeserializeFailed(e); } if (message != null) messageHandler(session, message); } isReadingHeader = true; return PackageHead.SizeOf; } }; return handler; }