📄 rudpsocket.cs
字号:
namespace NCindy.Protocol.RUDP
{
using NCindy.Protocol.RUDP.MTUTuning;
using NCindy.Protocol.RUDP.Packet;
using NCindy.Protocol.RUDP.SACK;
using NCindy.Protocol.RUDP.Stack;
using NCindy.Protocol.RUDP.Window;
using NCindy.Protocol.RUDP.Window.BIC;
using NCindy.Protocol.RUDP.Window.CUBIC;
using NCindy.Protocol.RUDP.Window.Reno;
using NCindy.Protocol.RUDP.Window.Tahoe;
using NCindy.Threading;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
public sealed class RUDPSocket
{
internal List<RUDPSocket> _acceptedRUDPSockets;
internal RUDPAcceptIAsyncResult _asyncResultAccept;
internal RUDPConnectIAsyncResult _asyncResultConnect;
internal RUDPReceiveIAsyncResult _asyncResultReceive;
internal long _bandwidth;
internal long _bandwidthResponse01TS;
internal byte[] _connectionId;
internal int _controlThreadId;
internal AbstractWindow _controlWindow;
internal double _deltaRtt;
internal int _fastRetransmitEndPacketId;
internal int _fastRetransmitStartPacketId;
internal LinkedList<FragmentInformation> _fragments;
internal ReaderWriterLockSlim _fragmentsLock;
internal int _handle;
internal object _handleNextUserPacketLock;
internal IngoingList _incomingPackets;
internal bool _isRendezVousMode;
internal bool _isShutingDown;
internal long _lastACKSendTS;
internal long _lastBandwidthTS;
internal long _lastSendTS;
internal int _mtu;
internal List<NATHistoryPoint> _NATEndPointsHistory;
private RUDPSocketNetworkInformation _networkInformation;
internal int _ougoingPacketId;
internal List<RUDPOutgoingPacket> _outgoingPackets;
internal ReaderWriterLockSlim _outgoingPacketsLock;
internal PhysicalSocket _physical;
internal PMTUDiscovery _pmtuDiscovery;
internal int _receiveSize;
internal IPEndPoint _remoteEndPoint;
internal double _rto;
internal double _rtt;
internal SACKWindow _sackWindow;
internal int _sendSize;
internal long _sequence;
internal RUDPSocketStatus _status;
internal long _sto;
internal bool _usePMTUDiscovery;
internal static int DefaultConnectionTimeOut = 0xea60;
internal static int LastHandle = 0;
internal static int LockTimeOut = -1;
public RUDPSocket() : this(RUDPCongestionControl.TCPReno)
{
}
public RUDPSocket(RUDPCongestionControl congestionControl)
{
this._controlThreadId = -1;
this._status = RUDPSocketStatus.Closed;
this._fragmentsLock = new ReaderWriterLockSlim();
this._fragments = new LinkedList<FragmentInformation>();
this._outgoingPacketsLock = new ReaderWriterLockSlim();
this._outgoingPackets = new List<RUDPOutgoingPacket>();
this._handleNextUserPacketLock = new object();
this._incomingPackets = new IngoingList();
this._acceptedRUDPSockets = new List<RUDPSocket>();
this._receiveSize = 0x19000;
this._sendSize = 0x19000;
this._lastACKSendTS = -1;
this._usePMTUDiscovery = true;
this._mtu = -1;
this._fastRetransmitStartPacketId = -1;
this._fastRetransmitEndPacketId = -1;
switch (congestionControl)
{
case RUDPCongestionControl.TCPTahoe:
this._controlWindow = new NCindy.Protocol.RUDP.Window.Tahoe.CongestionWindow(this);
break;
case RUDPCongestionControl.TCPReno:
this._controlWindow = new NCindy.Protocol.RUDP.Window.Reno.CongestionWindow(this);
break;
case RUDPCongestionControl.TCPBIC:
this._controlWindow = new NCindy.Protocol.RUDP.Window.BIC.CongestionWindow(this);
break;
case RUDPCongestionControl.TCPCUBIC:
this._controlWindow = new NCindy.Protocol.RUDP.Window.CUBIC.CongestionWindow(this);
break;
}
this.Reset(RUDPSocketStatus.Closed);
this._handle = LastHandle;
Interlocked.Increment(ref LastHandle);
this._networkInformation = new RUDPSocketNetworkInformation(this);
}
public RUDPSocket Accept()
{
IAsyncResult asyncResult = this.BeginAccept(null, null);
return this.EndAccept(asyncResult);
}
private void AutomaticBind()
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
this.Bind(endPoint);
}
public IAsyncResult BeginAccept(AsyncCallback callback, object state)
{
RUDPAcceptIAsyncResult result = new RUDPAcceptIAsyncResult(this, callback, state);
Interlocked.Exchange<RUDPAcceptIAsyncResult>(ref this._asyncResultAccept, result);
if (this._acceptedRUDPSockets.get_Count() > 0)
{
RUDPSocket acceptedSocket = this._acceptedRUDPSockets.get_Item(0);
lock (this._acceptedRUDPSockets)
{
this._acceptedRUDPSockets.RemoveAt(0);
}
this.OnEndAccept(acceptedSocket);
return result;
}
this._physical.BeginAccept(this, callback, state);
return result;
}
public IAsyncResult BeginConnect(IPEndPoint remoteEP, AsyncCallback callback, object state)
{
if (this._physical == null)
{
this.AutomaticBind();
}
this._connectionId = GenerateUniqueId();
RUDPConnectIAsyncResult result = new RUDPConnectIAsyncResult(this, callback, state);
Interlocked.Exchange<RUDPConnectIAsyncResult>(ref this._asyncResultConnect, result);
this._remoteEndPoint = remoteEP;
RUDPSocketError error = this._physical.BeginConnect(this, DefaultConnectionTimeOut);
if (error != RUDPSocketError.Success)
{
Interlocked.Exchange<RUDPConnectIAsyncResult>(ref this._asyncResultConnect, null);
this._remoteEndPoint = null;
throw new RUDPSocketException(error);
}
return result;
}
public IAsyncResult BeginReceive(AsyncCallback callback, object state)
{
SocketError errorCode = 0;
return this.BeginReceive(out errorCode, callback, state);
}
public IAsyncResult BeginReceive(out SocketError errorCode, AsyncCallback callback, object state)
{
RUDPReceiveIAsyncResult result = new RUDPReceiveIAsyncResult(this, callback, state);
Interlocked.Exchange<RUDPReceiveIAsyncResult>(ref this._asyncResultReceive, result);
errorCode = 0;
this.HandleNextUserPacket(true);
return result;
}
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, out RUDPSocketError errorCode, AsyncCallback callback, object state)
{
return this.BeginSend(buffer, offset, size, out errorCode, callback, state, true);
}
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, out RUDPSocketError errorCode, AsyncCallback callback, object state, bool reliable)
{
RUDPSendIAsyncResult asyncResult = new RUDPSendIAsyncResult(this, callback, state, size);
errorCode = RUDPStack.SendPayload(this, buffer, offset, size, reliable, asyncResult);
if (errorCode != RUDPSocketError.Success)
{
return null;
}
return asyncResult;
}
public void Bind(IPEndPoint endPoint)
{
this._physical = RUDPStack.GetInstance(endPoint);
}
public void Close()
{
this._physical.Close(this);
}
public void Connect(IPEndPoint endPoint)
{
IAsyncResult asyncResult = this.BeginConnect(endPoint, null, null);
this.EndConnect(asyncResult);
if (this._status == RUDPSocketStatus.Closed)
{
throw new SocketException();
}
}
public RUDPSocket EndAccept(IAsyncResult asyncResult)
{
RUDPAcceptIAsyncResult result = asyncResult as RUDPAcceptIAsyncResult;
result.EndInvoke(true);
return result.AcceptedSocket;
}
public void EndConnect(IAsyncResult asyncResult)
{
((RUDPConnectIAsyncResult) asyncResult).EndInvoke(true);
}
public byte[] EndReceive(IAsyncResult asyncResult)
{
RUDPReceiveIAsyncResult result = asyncResult as RUDPReceiveIAsyncResult;
result.EndInvoke(false);
if (result.SocketError != RUDPSocketError.Success)
{
return null;
}
return result.Packet.Payload;
}
public int EndSend(IAsyncResult asyncResult)
{
RUDPSendIAsyncResult result = asyncResult as RUDPSendIAsyncResult;
result.EndInvoke(false);
if (result.SocketError != RUDPSocketError.Success)
{
return -1;
}
return result._size;
}
internal static byte[] GenerateUniqueId()
{
return Guid.NewGuid().ToByteArray();
}
internal void HandleNextUserPacket(bool forceAsyncCall)
{
if (this._asyncResultReceive != null)
{
RUDPReceiveIAsyncResult asyncResult;
RUDPIngoingPacket packet = null;
lock (this._handleNextUserPacketLock)
{
if (this._incomingPackets.Count >= 1)
{
asyncResult = this._asyncResultReceive;
if (this._asyncResultReceive != null)
{
goto Label_0060;
}
}
return;
Label_0039:
packet = this._incomingPackets.RemoveNextPacket();
if (packet == null)
{
return;
}
if (packet.Channel == RUDPPacketChannel.UserPacket)
{
goto Label_006E;
}
this._controlWindow.OnReceiveProcessed(packet);
Label_0060:
if (this._incomingPackets.Count > 0)
{
goto Label_0039;
}
Label_006E:
if (packet == null)
{
return;
}
this._asyncResultReceive = null;
}
if (asyncResult != null)
{
this._controlWindow.OnReceiveProcessed(packet);
this.OnEndReceive(RUDPSocketError.Success, packet, forceAsyncCall, asyncResult);
}
}
}
public void Listen(int max)
{
}
internal void OnDisconnected(RUDPSocketError error)
{
this._connectionId = null;
this.OnEndConnect(error);
RUDPReceiveIAsyncResult asyncResult = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -