📄 sackwindow.cs
字号:
namespace NCindy.Protocol.RUDP.SACK
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
internal sealed class SACKWindow
{
private int _acksCount;
private List<SACKSlot> _slots = new List<SACKSlot>();
internal SACKWindow()
{
SACKSlot slot = new SACKSlot(-1, -1);
slot.ACKsCount = 0;
this._slots.Add(slot);
}
[Conditional("CHECK_SACKSCOUNT")]
private void CheckACKCount()
{
int num = 0;
for (int i = 0; i < this._slots.get_Count(); i++)
{
num += this._slots.get_Item(i).ACKsCount;
}
if (num != this._acksCount)
{
Console.WriteLine("");
}
}
internal void GetSLACKSlots(out SACKSlot slot1, out SACKSlot slot2, out SACKSlot slot3, out SACKSlot slot4)
{
slot1 = null;
slot2 = null;
slot3 = null;
slot4 = null;
lock (this)
{
if (this._slots.get_Item(0).StartPacketId >= 0)
{
slot1 = this._slots.get_Item(0).Clone();
this._slots.get_Item(0).ACKsCount = 0;
Interlocked.Exchange(ref this._acksCount, this._acksCount - slot1.ACKsCount);
for (int i = 1; i < this._slots.get_Count(); i++)
{
SACKSlot slot = this._slots.get_Item(i);
if (slot.ACKsCount > 0)
{
Interlocked.Exchange(ref this._acksCount, this._acksCount - slot.ACKsCount);
slot.ACKsCount = 0;
if (slot2 == null)
{
slot2 = slot.Clone();
}
else if (slot3 == null)
{
slot3 = slot.Clone();
}
else if (slot4 == null)
{
slot4 = slot.Clone();
break;
}
}
}
}
}
}
internal void OnReceivePacket(int packetId)
{
Monitor.Enter(this);
try
{
SACKSlot slot2;
for (int i = 0; i < this._slots.get_Count(); i++)
{
SACKSlot slot = this._slots.get_Item(i);
if ((packetId >= slot.StartPacketId) && (packetId <= slot.EndPacketId))
{
slot.ACKsCount++;
return;
}
if ((slot.EndPacketId + 1) == packetId)
{
slot.EndPacketId++;
slot.ACKsCount++;
if (slot.StartPacketId < 0)
{
slot.StartPacketId = 0;
}
if (((i + 1) < this._slots.get_Count()) && ((slot.EndPacketId + 1) == this._slots.get_Item(i + 1).StartPacketId))
{
i++;
slot.EndPacketId = this._slots.get_Item(i).EndPacketId;
slot.ACKsCount += this._slots.get_Item(i).ACKsCount;
this._slots.RemoveAt(i);
}
return;
}
if (packetId < slot.StartPacketId)
{
if (packetId == (slot.StartPacketId - 1))
{
slot.StartPacketId--;
slot.ACKsCount++;
}
else
{
slot2 = new SACKSlot(packetId, packetId);
this._slots.Insert(i, slot2);
}
return;
}
}
slot2 = new SACKSlot(packetId, packetId);
this._slots.Add(slot2);
}
finally
{
Interlocked.Increment(ref this._acksCount);
Monitor.Exit(this);
}
}
internal List<SACKSlot> PrepareACKList()
{
List<SACKSlot> list = new List<SACKSlot>();
lock (this)
{
for (int i = 1; i < this._slots.get_Count(); i++)
{
SACKSlot slot = this._slots.get_Item(i);
if (slot.ACKsCount > 0)
{
slot.ACKsCount = 0;
list.Add(slot.Clone());
}
}
if ((this._slots.get_Item(0).StartPacketId > -1) && ((list.get_Count() > 1) || (this._slots.get_Item(0).ACKsCount > 0)))
{
this._slots.get_Item(0).ACKsCount = 0;
list.Insert(0, this._slots.get_Item(0).Clone());
}
Interlocked.Exchange(ref this._acksCount, 0);
}
return list;
}
internal int ACKCount
{
get
{
return this._acksCount;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -