protected override void NotifyPacketReceived(TransportPacket packet) { if (packet.Length < PacketHeaderSize) { throw new TransportError(this, "should not receive datagrams whose size is less than PacketHeaderSize bytes", packet); } uint packetSeqNo = 0; packet.BytesAt(0, 4, (b,offset) => packetSeqNo = DataConverter.Converter.ToUInt32(b, offset)); packet.RemoveBytes(0, 4); // We handle wrap around by checking if the difference between the // packet-seqno and the expected next packet-seqno > uint.MaxValue / 2 // After all, it's unlikely that 2 billion packets will mysteriously disappear! if (packetSeqNo < nextIncomingPacketSeqNo && nextIncomingPacketSeqNo - packetSeqNo < uint.MaxValue / 2) { return; } nextIncomingPacketSeqNo = packetSeqNo + 1; // pass it on base.NotifyPacketReceived(packet); }
public void TestByteAt() { TransportPacket packet = new TransportPacket(); packet.Append(new byte[] {0, 1, 2, 3}); packet.Append(new byte[] {4, 5, 6, 7, 8}); packet.Append(new byte[] {9}); for(int i = 0; i < 10; i++) { Assert.AreEqual(i, packet.ByteAt(i)); packet.BytesAt(i, 1, (b,offset) => Assert.AreEqual(i, b[offset])); } packet.BytesAt(0, 10, (bytes, offset) => { for(int i = 0; i < 10; i++) { Assert.AreEqual(i, bytes[i]); } }); try { packet.ByteAt(10); Assert.Fail("Should have thrown ArgumentOutOfRange"); } catch (ArgumentOutOfRangeException) { /*ignore*/ } try { packet.BytesAt(10,1, (b,o) => Assert.Fail("should have thrown AOOR")); Assert.Fail("Should have thrown ArgumentOutOfRange"); } catch (ArgumentOutOfRangeException) { /*ignore*/ } try { packet.BytesAt(8, 8, (b, o) => Assert.Fail("should have thrown AOOR")); Assert.Fail("Should have thrown ArgumentOutOfRange"); } catch (ArgumentOutOfRangeException) { /*ignore*/ } CheckDisposed(packet); CheckForUndisposedSegments(); }
protected virtual uint ProcessHeader(TransportPacket header) { uint headerLength = 0; header.BytesAt(0, 4, (b, offset) => headerLength = DataConverter.Converter.ToUInt32(b, offset)); return headerLength; }