📄 rudpstack.cs
字号:
return information;
}
internal static RUDPOutgoingPacket NewOutgoingPacket(int packetId, long sequence, byte[] payload, RUDPPacketChannel channel)
{
RUDPOutgoingPacket packet = null;
if (_outgoingPacketsPools.Count <= 0)
{
for (int i = 0; i < 100; i++)
{
_outgoingPacketsPools.Enqueue(new RUDPOutgoingPacket(-1, (long) (-1), null, RUDPPacketChannel.Undefined));
}
return new RUDPOutgoingPacket(packetId, sequence, payload, channel);
}
packet = (RUDPOutgoingPacket) _outgoingPacketsPools.Dequeue();
packet.Reset();
packet.PacketId = packetId;
packet.Payload = payload;
packet.Channel = channel;
packet.Sequence = sequence;
return packet;
}
internal static void OnDisconnected(RUDPSocket rudp, DisconnectionReason reason)
{
if (rudp._status != RUDPSocketStatus.Closed)
{
rudp._outgoingPacketsLock.EnterWriteLock();
rudp._outgoingPackets.Clear();
rudp._outgoingPacketsLock.ExitWriteLock();
rudp.Reset(RUDPSocketStatus.Closed);
if (reason != DisconnectionReason.ConnectionClosed)
{
RUDPSocketError connectionReset = RUDPSocketError.ConnectionReset;
if (reason == DisconnectionReason.SocketError)
{
connectionReset = RUDPSocketError.SocketError;
}
if (reason == DisconnectionReason.TimeOut)
{
connectionReset = RUDPSocketError.ConnectionReset;
}
rudp._physical.OnDisconnected(rudp, connectionReset);
}
}
}
private static void OnEndReceive(IAsyncResult result)
{
RUDPPacketChannel undefined;
PhysicalSocket state = (PhysicalSocket) result.AsyncState;
EndPoint remoteEP = state._canReceiveFromEndPoint;
EndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
int length = -1;
try
{
length = state._socket.EndReceiveFrom(result, ref endPoint);
}
catch (SocketException exception)
{
if (exception.ErrorCode == 0x3e3)
{
state._socket.BeginReceiveFrom(state._receiveBuffer, 0, state._receiveBuffer.Length, SocketFlags.None, ref remoteEP, new AsyncCallback(RUDPStack.OnEndReceive), state);
}
else
{
if (exception.ErrorCode == 0x2746)
{
state._socket.BeginReceiveFrom(state._receiveBuffer, 0, state._receiveBuffer.Length, SocketFlags.None, ref remoteEP, new AsyncCallback(RUDPStack.OnEndReceive), state);
goto Label_00C4;
}
OnSocketUnhandledError(state, endPoint as IPEndPoint, exception.get_SocketErrorCode());
}
return;
}
Label_00C4:
undefined = RUDPPacketChannel.Undefined;
int packetId = -2;
int advertisedWindowSize = 0;
SACKSlot slot = null;
SACKSlot slot2 = null;
SACKSlot slot3 = null;
SACKSlot slot4 = null;
byte[] packetPayload = null;
if (_isStackRunning)
{
byte[] connectionId;
DecodePayload(state, state._receiveBuffer, length, endPoint as IPEndPoint, out connectionId, out undefined, out packetId, out advertisedWindowSize, out slot, out slot2, out slot3, out slot4, out packetPayload);
state._socket.BeginReceiveFrom(state._receiveBuffer, 0, state._receiveBuffer.Length, SocketFlags.None, ref remoteEP, new AsyncCallback(RUDPStack.OnEndReceive), state);
HandlePacket(state, endPoint as IPEndPoint, connectionId, undefined, packetId, advertisedWindowSize, slot, slot2, slot3, slot4, packetPayload);
}
}
internal static void OnSocketUnhandledError(RUDPSocket rudp, RUDPSocketError error, RUDPSendIAsyncResult sendAsyncResult)
{
OnDisconnected(rudp, DisconnectionReason.SocketError);
if (rudp._status == RUDPSocketStatus.Connecting)
{
rudp.OnEndConnect(error);
}
else
{
if (sendAsyncResult != null)
{
rudp.OnEndSend(error, sendAsyncResult);
}
RUDPReceiveIAsyncResult asyncResult = null;
Interlocked.Exchange<RUDPReceiveIAsyncResult>(ref asyncResult, rudp._asyncResultReceive);
if (asyncResult != null)
{
Interlocked.Exchange<RUDPReceiveIAsyncResult>(ref rudp._asyncResultReceive, null);
rudp.OnEndReceive(error, null, true, asyncResult);
}
}
}
internal static void OnSocketUnhandledError(PhysicalSocket physical, IPEndPoint remoteEndPoint, SocketError error)
{
RUDPSocket rudp;
physical._connectedRDUPsLock.EnterReadLock();
try
{
if (!physical._connectedRDUPs.TryGetValue(remoteEndPoint, ref rudp))
{
return;
}
}
finally
{
physical._connectedRDUPsLock.ExitReadLock();
}
OnSocketUnhandledError(rudp, SocketErrorToRUDPSocketError(error), null);
}
internal static bool PushPacketToSend(RUDPSocket rudp, bool reliablePacket, RUDPPacketChannel channel, byte[] payload, int offset, int payloadLength)
{
int packetId = -1;
if (reliablePacket)
{
packetId = Interlocked.Increment(ref rudp._ougoingPacketId);
}
SACKSlot slot = null;
SACKSlot slot2 = null;
SACKSlot slot3 = null;
SACKSlot slot4 = null;
rudp._sackWindow.GetSLACKSlots(out slot, out slot2, out slot3, out slot4);
byte[] buffer = MakePacketPayload(rudp, packetId, channel, slot, slot2, slot3, slot4, payload, offset, payloadLength);
RUDPOutgoingPacket packet = NewOutgoingPacket(packetId, rudp._sequence, buffer, channel);
packet.CurrentCwnd = rudp._controlWindow.CWND;
if (reliablePacket)
{
rudp._controlWindow.OnSend(packetId, rudp._sequence, payloadLength);
Interlocked.Exchange(ref rudp._sequence, rudp._sequence + payloadLength);
}
if (reliablePacket)
{
rudp._outgoingPacketsLock.EnterWriteLock();
rudp._outgoingPackets.Add(packet);
rudp._outgoingPacketsLock.ExitWriteLock();
}
packet.TSFirstSend = HiResTimer.MicroSeconds;
if (!SocketSendPacket(rudp, packet, packet.Payload, packet.TSFirstSend))
{
return false;
}
return true;
}
private static void RegisterPhysicalSocket(PhysicalSocket physical)
{
EndPoint remoteEP = physical._canReceiveFromEndPoint;
physical._socket.BeginReceiveFrom(physical._receiveBuffer, 0, physical._receiveBuffer.Length, SocketFlags.None, ref remoteEP, new AsyncCallback(RUDPStack.OnEndReceive), physical);
}
internal static void RegisterRUDPSocket(RUDPSocket rudp)
{
int index = -1;
int num2 = 0x7fffffff;
for (int i = 0; i < _controlThreadInformations.Length; i++)
{
if (_controlThreadInformations[i]._rudpSockets.get_Count() < num2)
{
index = i;
num2 = _controlThreadInformations[i]._rudpSockets.get_Count();
}
}
if (rudp._controlThreadId <= -1)
{
rudp._controlThreadId = index;
_controlThreadInformations[index]._rudpSocketsLock.EnterWriteLock();
if (!_controlThreadInformations[index]._rudpSockets.Contains(rudp))
{
_controlThreadInformations[index]._rudpSockets.Add(rudp);
}
_controlThreadInformations[index]._rudpSocketsLock.ExitWriteLock();
}
}
internal static void ReleaseFragmentInformation(FragmentInformation fragment)
{
lock (_fragmentsPools)
{
_fragmentsPools.Enqueue(fragment);
}
}
internal static void ReleaseInstance(PhysicalSocket physical)
{
lock (_physicals)
{
physical.Dispose();
_physicals.Remove((IPEndPoint) physical._socket.LocalEndPoint);
}
}
internal static void ReleaseOutgoingPacket(RUDPOutgoingPacket packet)
{
_outgoingPacketsPools.Enqueue(packet);
PayloadManager.Deallocate(packet.Channel, packet.Payload);
packet.Payload = null;
}
private static bool RetransmissionTimer(RUDPSocket rudp, long now, ControlThreadInformation controlInformation)
{
int num = rudp._outgoingPackets.get_Count();
bool flag = false;
controlInformation._chargeCheckStopWatch.Reset();
controlInformation._chargeCheckStopWatch.Start();
for (int i = 0; i < num; i++)
{
rudp._outgoingPacketsLock.EnterReadLock();
RUDPOutgoingPacket packet = rudp._outgoingPackets.get_Item(i);
rudp._outgoingPacketsLock.ExitReadLock();
if (packet.TSLastSend >= 0)
{
if (packet.IsACKed)
{
rudp._outgoingPacketsLock.EnterWriteLock();
rudp._outgoingPackets.RemoveAt(i);
rudp._outgoingPacketsLock.ExitWriteLock();
ReleaseOutgoingPacket(packet);
i--;
num--;
}
else
{
if ((packet.TSFirstSend > -1) && ((now - packet.TSFirstSend) > rudp._sto))
{
OnDisconnected(rudp, DisconnectionReason.TimeOut);
return true;
}
bool flag2 = (packet.PacketId >= rudp._fastRetransmitStartPacketId) && (packet.PacketId <= rudp._fastRetransmitEndPacketId);
if (flag2 || ((now - packet.TSLastSend) >= rudp._rto))
{
flag |= flag2;
SACKSlot slot = null;
SACKSlot slot2 = null;
SACKSlot slot3 = null;
SACKSlot slot4 = null;
rudp._sackWindow.GetSLACKSlots(out slot, out slot2, out slot3, out slot4);
UpdatePacketPayload(packet.Payload, slot, slot2, slot3, slot4);
if (SocketSendPacket(rudp, packet, packet.Payload, now))
{
rudp._controlWindow.OnTimeOut(packet);
packet.Retransmission++;
}
if (controlInformation._chargeCheckStopWatch.get_ElapsedMilliseconds() > 0)
{
return false;
}
}
}
}
}
if (flag)
{
rudp.OnEndFastRetransmit();
}
return true;
}
private static bool SendFragments(FragmentInformation fragments, ControlThreadInformation controlInformation)
{
controlInformation._chargeCheckStopWatch.Reset();
controlInformation._chargeCheckStopWatch.Start();
while (fragments.Size > 0)
{
int num = fragments.rudp._mtu - 0x5b;
int payloadLength = Math.Min(num, fragments.Size);
if (fragments.IsReliable && !fragments.rudp._controlWindow.CanSend(payloadLength))
{
return false;
}
if (!PushPacketToSend(fragments.rudp, fragments.IsReliable, RUDPPacketChannel.UserPacket, fragments.Payload, fragments.Offset, payloadLength))
{
fragments.Error = RUDPSocketError.SocketError;
if (fragments.AsyncResult != null)
{
OnSocketUnhandledError(fragments.rudp, fragments.Error, fragments.AsyncResult);
}
return true;
}
fragments.Size -= payloadLength;
fragments.Offset += payloadLength;
if ((fragments.Size > 0) && (controlInformation._chargeCheckStopWatch.get_ElapsedMilliseconds() > 0))
{
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -