Segment.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using System;
  2. using System.Buffers;
  3. using System.Diagnostics.CodeAnalysis;
  4. using System.IO;
  5. using System.Runtime.CompilerServices;
  6. using System.Runtime.InteropServices;
  7. namespace ET
  8. {
  9. // KCP Segment Definition
  10. internal struct SegmentStruct:IDisposable
  11. {
  12. public Kcp.SegmentHead SegHead;
  13. public uint resendts;
  14. public int rto;
  15. public uint fastack;
  16. public uint xmit;
  17. private byte[] buffer;
  18. private ArrayPool<byte> arrayPool;
  19. public bool IsNull => this.buffer == null;
  20. public int WrittenCount
  21. {
  22. get => (int) this.SegHead.len;
  23. private set => this.SegHead.len = (uint) value;
  24. }
  25. public Span<byte> WrittenBuffer => this.buffer.AsSpan(0, (int) this.SegHead.len);
  26. public Span<byte> FreeBuffer => this.buffer.AsSpan(WrittenCount);
  27. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  28. public SegmentStruct(int size, ArrayPool<byte> arrayPool)
  29. {
  30. this.arrayPool = arrayPool;
  31. buffer = arrayPool.Rent(size);
  32. this.SegHead = new Kcp.SegmentHead() { len = 0 };
  33. this.SegHead = default;
  34. this.resendts = default;
  35. this.rto = default;
  36. this.fastack = default;
  37. this.xmit = default;
  38. }
  39. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  40. public void Encode(Span<byte> data, ref int size)
  41. {
  42. Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(data),this.SegHead);
  43. size += Unsafe.SizeOf<Kcp.SegmentHead>();
  44. }
  45. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  46. public void Advance(int count)
  47. {
  48. this.WrittenCount += count;
  49. }
  50. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  51. public void Dispose()
  52. {
  53. arrayPool.Return(this.buffer);
  54. }
  55. }
  56. // internal class Segment
  57. // {
  58. // internal uint conv; // conversation
  59. // internal byte cmd; // command, e.g. Kcp.CMD_ACK etc.
  60. // // fragment (sent as 1 byte).
  61. // // 0 if unfragmented, otherwise fragment numbers in reverse: N,..,32,1,0
  62. // // this way the first received segment tells us how many fragments there are.
  63. // internal byte frg;
  64. // internal ushort wnd; // window size that the receive can currently receive
  65. // internal uint ts; // timestamp
  66. // internal uint sn; // sequence number
  67. // internal uint una;
  68. // internal uint resendts; // resend timestamp
  69. // internal int rto;
  70. // internal uint fastack;
  71. // internal uint xmit; // retransmit count
  72. //
  73. // internal MemoryStream data = new MemoryStream(Kcp.MTU_DEF);
  74. //
  75. // [MethodImpl(MethodImplOptions.AggressiveInlining)]
  76. // internal int Encode(byte[] ptr, int offset)
  77. // {
  78. // int previousPosition = offset;
  79. //
  80. // var segHead = new Kcp.SegmentHead()
  81. // {
  82. // conv = this.conv,
  83. // cmd = (byte) this.cmd,
  84. // frg = (byte) frg,
  85. // wnd = (ushort) this.wnd,
  86. // ts = this.ts,
  87. // sn = this.sn,
  88. // una = this.una,
  89. // len = (uint) this.data.Position,
  90. // };
  91. //
  92. // Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(ptr.AsSpan(offset)),segHead);
  93. // offset+=Unsafe.SizeOf<Kcp.SegmentHead>();
  94. //
  95. // int written = offset - previousPosition;
  96. // return written;
  97. // }
  98. //
  99. // // reset to return a fresh segment to the pool
  100. // [MethodImpl(MethodImplOptions.AggressiveInlining)]
  101. // internal void Reset()
  102. // {
  103. // conv = 0;
  104. // cmd = 0;
  105. // frg = 0;
  106. // wnd = 0;
  107. // ts = 0;
  108. // sn = 0;
  109. // una = 0;
  110. // rto = 0;
  111. // xmit = 0;
  112. // resendts = 0;
  113. // fastack = 0;
  114. //
  115. // // keep buffer for next pool usage, but reset length (= bytes written)
  116. // data.SetLength(0);
  117. // }
  118. // }
  119. }