diff options
Diffstat (limited to 'Tools')
7 files changed, 119 insertions, 37 deletions
diff --git a/Tools/Hazel-Networking/Hazel.UnitTests/MessageReaderTests.cs b/Tools/Hazel-Networking/Hazel.UnitTests/MessageReaderTests.cs index 6cf4ba8..7a073ae 100644 --- a/Tools/Hazel-Networking/Hazel.UnitTests/MessageReaderTests.cs +++ b/Tools/Hazel-Networking/Hazel.UnitTests/MessageReaderTests.cs @@ -125,7 +125,7 @@ namespace Hazel.UnitTests reader.Length = msg.Length; var zero = reader.ReadMessage(); - + var one = reader.ReadMessage(); var two = one.ReadMessage(); var three = two.ReadMessage(); @@ -218,6 +218,27 @@ namespace Hazel.UnitTests const byte Test5 = 55; const byte TestInsert = 66; +/* +2 length=1 +1 tag=0 +1 Test0=11 + +2 length=11 +1 tag=12 + 2 length=8 + 1 tag=23 + 2 length=1 + 1 tag=34 + 1 Test3=33 + + 2 length=1 + 1 tag=45 + 1 Test4=44 +2 length=1 +1 tag=56 +1 Test5=55 +*/ + var msg = new MessageWriter(2048); msg.StartMessage(0); msg.Write(Test0); @@ -247,6 +268,12 @@ namespace Hazel.UnitTests writer.StartMessage(5); writer.Write(TestInsert); writer.EndMessage(); +/* +1 SendOption.None +2 length=2 +1 tag=5 +1 TestInsert=66 + */ reader.ReadMessage(); var one = reader.ReadMessage(); diff --git a/Tools/Hazel-Networking/Hazel.lutconfig b/Tools/Hazel-Networking/Hazel.lutconfig new file mode 100644 index 0000000..87625ea --- /dev/null +++ b/Tools/Hazel-Networking/Hazel.lutconfig @@ -0,0 +1,6 @@ +<LUTConfig Version="1.0"> + <Repository>..\..\</Repository> + <ParallelBuilds>true</ParallelBuilds> + <ParallelTestRuns>true</ParallelTestRuns> + <TestCaseTimeout>180000</TestCaseTimeout> +</LUTConfig>
\ No newline at end of file diff --git a/Tools/Hazel-Networking/Hazel/MessageReader.cs b/Tools/Hazel-Networking/Hazel/MessageReader.cs index bd3b0d8..b6e35de 100644 --- a/Tools/Hazel-Networking/Hazel/MessageReader.cs +++ b/Tools/Hazel-Networking/Hazel/MessageReader.cs @@ -1,4 +1,5 @@ -using System; +#define UNIT_TEST +using System; using System.IO; using System.Linq; using System.Runtime.CompilerServices; @@ -6,32 +7,37 @@ using System.Text; namespace Hazel { + /// <summary> + /// + /// </summary> public class MessageReader : IRecyclable { public static readonly ObjectPool<MessageReader> ReaderPool = new ObjectPool<MessageReader>(() => new MessageReader()); - public byte[] Buffer; - public byte Tag; + public byte[] Buffer; // √ 缓冲区,会被子协议共享这个缓冲区 + public byte Tag; // √ 协议名 - public int Length; // 总长度 - public int Offset; // length和tag后面 + public int Length; // √ 协议长度,对应的是MessageWriter里写入的2bytes包长度(不含length和tag) + public int Offset; // √ length和tag后面的位置(在Buffer中的位置),不是游标,不会随读取发生改变。会影响readHead的值 + + //数据位于Buffer中Offset索引开始Length长度,协议位于Buffer中Offset-3开始的Length+3长度 public int BytesRemaining => this.Length - this.Position; - private MessageReader Parent; + private MessageReader Parent; // 保存父协议索引,和父协议共享父协议的Buffer public int Position { get { return this._position; } set { - this._position = value; + this._position = value; // value是 this.readHead = value + Offset; } } - private int _position; - private int readHead; + private int _position; // √ 读取游标,相对于协议内容部分的偏移,从0开始,子协议也是从0开始,不是在Buffer中的索引 + private int readHead; // √ 读取游标,协议头部在Buffer中的位置,参考ReadMessage() public static MessageReader GetSized(int minSize) { @@ -65,10 +71,15 @@ namespace Hazel return output; } + /// <summary> + /// 创建一个新的message,保存source。用于缓存message,因为source所在的原父message可能会被销毁,如果需要延迟处理消息,需要拷贝一份新的 + /// </summary> + /// <param name="source"></param> + /// <returns></returns> public static MessageReader CopyMessageIntoParent(MessageReader source) { - var output = MessageReader.GetSized(source.Length + 3); - System.Buffer.BlockCopy(source.Buffer, source.Offset - 3, output.Buffer, 0, source.Length + 3); + var output = MessageReader.GetSized(source.Length + 3); //3=2bytes(length) + 1byte(tag) + System.Buffer.BlockCopy(source.Buffer, source.Offset - 3, output.Buffer, 0, source.Length + 3); output.Offset = 0; output.Position = 0; @@ -77,6 +88,11 @@ namespace Hazel return output; } + /// <summary> + /// 完全复制 一份 + /// </summary> + /// <param name="source"></param> + /// <returns></returns> public static MessageReader Get(MessageReader source) { var output = MessageReader.GetSized(source.Buffer.Length); @@ -96,7 +112,7 @@ namespace Hazel public static MessageReader Get(byte[] buffer, int offset) { // Ensure there is at least a header - if (offset + 3 > buffer.Length) return null; + if (offset + 3 > buffer.Length) return null; //3=length+tag var output = ReaderPool.GetObject(); @@ -104,7 +120,7 @@ namespace Hazel output.Offset = offset; output.Position = 0; - output.Length = output.ReadUInt16(); + output.Length = output.ReadUInt16(); // 读到的值为length output.Tag = output.ReadByte(); output.Offset += 3; @@ -121,22 +137,24 @@ namespace Hazel // Ensure there is at least a header if (this.BytesRemaining < 3) throw new InvalidDataException($"ReadMessage header is longer than message length: 3 of {this.BytesRemaining}"); - var output = new MessageReader(); + MessageReader output = new MessageReader(); output.Parent = this; output.Buffer = this.Buffer; - output.Offset = this.readHead; + output.Offset = this.readHead; // 下面会读取 output.Position = 0; + // 读length和tag的值并保存在字段里 output.Length = output.ReadUInt16(); output.Tag = output.ReadByte(); - output.Offset += 3; + // Offset, readHead齐步走,移到Length和Tag后面,_position=0 + output.Offset += 3; // 3=length+tag output.Position = 0; if (this.BytesRemaining < output.Length + 3) throw new InvalidDataException($"Message Length at Position {this.readHead} is longer than message length: {output.Length + 3} of {this.BytesRemaining}"); - this.Position += output.Length + 3; + this.Position += output.Length + 3; //跳过整个子协议 return output; } @@ -201,22 +219,29 @@ namespace Hazel } } + +#if UNIT_TEST // 我自己加的,作为备注 + /// <summary> + /// 仅用于单元测试的方法 + /// </summary> + /// <param name="reader">父reader</param> + /// <param name="writer"></param> public void InsertMessage(MessageReader reader, MessageWriter writer) { var temp = MessageReader.GetSized(reader.Buffer.Length); try { - var headerOffset = reader.Offset - 3; - var startOfMessage = reader.Offset; - var len = reader.Buffer.Length - startOfMessage; - int writerOffset = 3; + var headerOffset = reader.Offset - 3; // headerOffset是length+tag,这个方法仅仅接受reader不含sendoption的情况 + var startOfMessage = reader.Offset; // 头部后面的数据开始的索引 + var len = reader.Buffer.Length - startOfMessage; // 疑似写错了,应该是headerOffset + int writerOffset = 3;// √ 跳过header switch (writer.SendOption) { case SendOption.Reliable: writerOffset = 3; break; case SendOption.None: - writerOffset = 1; + writerOffset = 1; break; } @@ -236,6 +261,7 @@ namespace Hazel temp.Recycle(); } } +#endif private void AdjustLength(int offset, int amount) { @@ -266,7 +292,7 @@ namespace Hazel ReaderPool.PutObject(this); } - #region Read Methods +#region Read Methods public bool ReadBoolean() { byte val = this.FastByte(); @@ -427,7 +453,7 @@ namespace Hazel return output; } - #endregion +#endregion [MethodImpl(MethodImplOptions.AggressiveInlining)] private byte FastByte() diff --git a/Tools/Hazel-Networking/Hazel/MessageWriter.cs b/Tools/Hazel-Networking/Hazel/MessageWriter.cs index cbae11c..68280cd 100644 --- a/Tools/Hazel-Networking/Hazel/MessageWriter.cs +++ b/Tools/Hazel-Networking/Hazel/MessageWriter.cs @@ -6,12 +6,15 @@ using System.Text; namespace Hazel { /// <summary> - /// 嵌套结构的Message + /// 单向写入的Message,嵌套结构的Message,如果有嵌套,也只有一个header,子协议没有header + /// 整个结构都会被socket发送,参见UdpConnection.cs /// 结构: - /// ------------------------------------ - /// 2bytes (ushort) 包长度 - /// 1bytes (tag) 协议ID,在AmongUS里是tags.cs里定义的tag和subtag - /// ------------------------------------ + /// -------------header----------------- + /// 1bytes SendOption 是否是可靠传输 + /// (2bytes) (可靠传输用到的) + /// --------------数据------------------ + /// 2bytes 包长度(不含这2bytes和下面的tag 1byte) + /// 1bytes 协议ID,在AmongUS里是tags.cs里定义的tag和subtag /// 数据 包括嵌套的子协议 /// ------------------------------------ /// </summary> @@ -20,8 +23,8 @@ namespace Hazel public static int BufferSize = 64000; public static readonly ObjectPool<MessageWriter> WriterPool = new ObjectPool<MessageWriter>(() => new MessageWriter(BufferSize)); - public byte[] Buffer; - public int Length; // 总长度 + public byte[] Buffer; // 缓冲区,保存了整个包体,包括头部和内容 + public int Length; // 有效数据在buffer中的长度,可能包含多个嵌套子协议。Length>=Position public int Position; // 写入游标 public SendOption SendOption { get; private set; } @@ -86,6 +89,11 @@ namespace Hazel return output; } + /// <summary> + /// expected没有header + /// </summary> + /// <param name="expected"></param> + /// <returns></returns> public bool HasBytes(int expected) { if (this.SendOption == SendOption.None) diff --git a/Tools/Hazel-Networking/Hazel/Udp/UdpClientConnection.cs b/Tools/Hazel-Networking/Hazel/Udp/UdpClientConnection.cs index f6da329..90aeb0d 100644 --- a/Tools/Hazel-Networking/Hazel/Udp/UdpClientConnection.cs +++ b/Tools/Hazel-Networking/Hazel/Udp/UdpClientConnection.cs @@ -205,9 +205,10 @@ namespace Hazel.Udp } #endif - var msg = MessageReader.GetSized(this.ReceiveBufferSize); + var msg = MessageReader.GetSized(this.ReceiveBufferSize);//һmessage try { + // BufferMessageWriterݣheader socket.BeginReceive(msg.Buffer, 0, msg.Buffer.Length, SocketFlags.None, ReadCallback, msg); } catch @@ -282,7 +283,7 @@ namespace Hazel.Udp //Begin receiving again try { - StartListeningForData(); + StartListeningForData(); //Ϣûasync awaitһwhileѯҪǶ } catch (SocketException e) { @@ -305,6 +306,7 @@ namespace Hazel.Udp DataReceivedRaw?.Invoke(msg.Buffer, msg.Length); #endif + //c //! ص㿴泤ʲô HandleReceive(msg, msg.Length); } diff --git a/Tools/Hazel-Networking/Hazel/Udp/UdpConnection.Reliable.cs b/Tools/Hazel-Networking/Hazel/Udp/UdpConnection.Reliable.cs index bed4738..cff403b 100644 --- a/Tools/Hazel-Networking/Hazel/Udp/UdpConnection.Reliable.cs +++ b/Tools/Hazel-Networking/Hazel/Udp/UdpConnection.Reliable.cs @@ -280,7 +280,18 @@ namespace Hazel.Udp ushort id; if (ProcessReliableReceive(message.Buffer, 1, out id)) { - InvokeDataReceived(SendOption.Reliable, message, 3, bytesReceived); + //c +/* + void InvokeDataReceived(SendOption sendOption, MessageReader buffer, int dataOffset, int bytesReceived) + { + buffer.Offset = dataOffset; + buffer.Length = bytesReceived - dataOffset; + buffer.Position = 0; + + InvokeDataReceived(buffer, sendOption); + } +*/ + InvokeDataReceived(SendOption.Reliable, message, 3, bytesReceived); // √ 3是header,不是length+tag } else { @@ -302,7 +313,7 @@ namespace Hazel.Udp byte b2 = bytes[offset + 1]; //Get the ID form the packet - id = (ushort)((b1 << 8) + b2); + id = (ushort)((b1 << 8) + b2); // 用于可靠传输的id /* * It gets a little complicated here (note the fact I'm actually using a multiline comment for once...) diff --git a/Tools/Hazel-Networking/Hazel/Udp/UdpConnection.cs b/Tools/Hazel-Networking/Hazel/Udp/UdpConnection.cs index e64576a..78f1788 100644 --- a/Tools/Hazel-Networking/Hazel/Udp/UdpConnection.cs +++ b/Tools/Hazel-Networking/Hazel/Udp/UdpConnection.cs @@ -77,7 +77,7 @@ namespace Hazel.Udp case SendOption.Reliable: ResetKeepAliveTimer(); - AttachReliableID(buffer, 1); + AttachReliableID(buffer, 1); // д֮ǰյڿɿID WriteBytesToConnection(buffer, buffer.Length); Statistics.LogReliableSend(buffer.Length - 3); break; @@ -132,6 +132,7 @@ namespace Hazel.Udp { //Handle reliable receives case (byte)SendOption.Reliable: + //c //! ReliableMessageReceive(message, bytesReceived); break; @@ -161,6 +162,7 @@ namespace Hazel.Udp break; case (byte)SendOption.None: + //c //! InvokeDataReceived(SendOption.None, message, 1, bytesReceived); Statistics.LogUnreliableReceive(bytesReceived - 1, bytesReceived); break; |