📄 udtsocket.cs
字号:
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return 0;
}
#endif
}
#endregion
#region REMOVED: GetOverlappedResult
/*
public void GetOverlappedResult(int overlappedIOHandle, ref int progress, bool wait)
{
API_Getoverlappedresult(_handle, overlappedIOHandle, ref progress, wait);
}
*/
#endregion
#region UDT Thread - ASync Management
// List of sockets waiting for accept
static List<AsyncAcceptRegistration> _acceptRegistrations = new List<AsyncAcceptRegistration>(100);
// List of sockets waiting for receive
static List<AsyncReceiveRegistration> _receiveRegistrations = new List<AsyncReceiveRegistration>(100);
static private void UDTThreadProcessing()
{
try
{
while (Thread.CurrentThread.IsAlive)
{
//---- Accept
for (int index = _acceptRegistrations.Count - 1; index > -1; index--)
{
Monitor.Enter(_acceptRegistrations);
AsyncAcceptRegistration registration = _acceptRegistrations[index];
Monitor.Exit(_acceptRegistrations);
if (registration.Socket.IsOnAccept)
{
// Stop "BeginAccept"
lock (_acceptRegistrations)
_acceptRegistrations.RemoveAt(index);
// Queue it for the call back
_processor.AddCommand(registration);
}
}
//---- Receive
for (int index = _receiveRegistrations.Count - 1; index > -1; index--)
{
Monitor.Enter(_receiveRegistrations);
AsyncReceiveRegistration registration = _receiveRegistrations[index];
Monitor.Exit(_receiveRegistrations);
if (!registration.Socket.Connected || registration.Socket.IsOnRead)
{
// Stop "BeginReceive"
lock (_receiveRegistrations)
_receiveRegistrations.RemoveAt(index);
// Queue it for the call back
_processor.AddCommand(registration);
}
}
//---- Like "Select" Wait for an event or 1 millisecond
API_WaitForEvent();
}
}
catch (ThreadInterruptedException)
{ }
}
#endregion
#region BeginAccept
public IAsyncResult BeginAccept(AsyncCallback callback, object state)
{
AsyncAcceptRegistration asyncRegistration = new AsyncAcceptRegistration(this, callback, state);
lock (_acceptRegistrations)
_acceptRegistrations.Add(asyncRegistration);
return null;
}
public UDTSocket EndAccept(IAsyncResult ar)
{
return (UDTSocket)((UDTAsyncResult)ar)._socket;
}
#endregion
#region BeginConnect
public IAsyncResult BeginConnect(IPEndPoint endPoint, AsyncCallback callback, object state)
{
AsyncConnectRegistration asyncRegistration = new AsyncConnectRegistration(this, endPoint, callback, state);
_processor.AddCommand(asyncRegistration);
return null;
}
public void EndConnect(IAsyncResult ar)
{
if (((UDTAsyncResult)ar).Exception != null)
{
throw ((UDTAsyncResult)ar).Exception;
}
}
#endregion
#region BeginReceive
public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state)
{
AsyncReceiveRegistration asyncRegistration = new AsyncReceiveRegistration(this, buffer, offset, size, socketFlags, callback, state);
lock (_receiveRegistrations)
_receiveRegistrations.Add(asyncRegistration);
return null;
}
public int EndReceive(IAsyncResult ar)
{
return ((UDTAsyncResult)ar)._size;
}
#endregion
#region BeginSend
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError error, AsyncCallback callback, object state)
{
error = SocketError.Success;
try
{
return BeginSend(buffer, offset, size, socketFlags, callback, state);
}
catch (Exception)
{
error = SocketError.SocketError;
return null;
}
}
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state)
{
AsyncSendRegistration asyncRegistration = new AsyncSendRegistration(this, buffer, offset, size, socketFlags, callback, state);
IntPtr pointer = GCHandle.ToIntPtr(GCHandle.Alloc(asyncRegistration));
if (UDT_ERROR == API_BeginSend(_handle, buffer, size, (int)socketFlags, pointer))
throw new UDTSocketException();
// HACK !!!!!
_processor.AddCommand(asyncRegistration);
return null;
}
private static void UDTEndSendCallback(IntPtr pointer)
{
AsyncSendRegistration asyncRegistration = (AsyncSendRegistration)GCHandle.FromIntPtr(pointer).Target;
_processor.AddCommand(asyncRegistration);
}
public int EndSend(IAsyncResult ar)
{
return ((UDTAsyncResult)ar)._size;
}
#endregion
#region IsOn...
public bool IsOnAccept
{
get
{
#if UDT_FULLTCP
List<System.Net.Sockets.Socket> list = new List<System.Net.Sockets.Socket>(1);
list.Add(_tcpSocket);
System.Net.Sockets.Socket.Select(list, null, null, 0);
if (list.Count < 1)
return false;
return true;
#else
return API_IsOnAccept(_handle);
#endif
}
}
public bool IsOnRead
{
get
{
#if UDT_FULLTCP
List<System.Net.Sockets.Socket> list = new List<System.Net.Sockets.Socket>(1);
list.Add(_tcpSocket);
System.Net.Sockets.Socket.Select(list, null, null, 0);
if (list.Count < 1)
return false;
return true;
#else
return API_IsOnRead(_handle);
#endif
}
}
public bool IsOnWrite
{
get
{
#if UDT_FULLTCP
return true;
#else
return API_IsOnWrite(_handle);
#endif
}
}
public bool IsOnError
{
get
{
#if UDT_FULLTCP
return false;
#else
return API_IsOnError(_handle);
#endif
}
}
#endregion
#region SetSocketOption
public void SetSocketOption(SocketOptionLevel optionLevel, UDTSocketOptionName optionName, int optionValue)
{
SetSocketOption(optionLevel, optionName, (object)optionValue);
}
public void SetSocketOption(SocketOptionLevel optionLevel, UDTSocketOptionName optionName, object optionValue)
{
#if UDT_FULLTCP
//_tcpSocket.SetSocketOption(optionLevel, optionName, optionValue);
#else
//---- UDT
int size = -1;
if (optionValue is int)
size = sizeof(int);
else if (optionValue is long)
size = sizeof(long);
else if (optionValue is LingerOption)
{
// If false it is the default behaviors.
// If true the socket "close" method will wait that all the sending data have been send and
// that he has receive the ack. The close method does not return until all the data is delivered
// or until "time" (second linger option) has expired).
/*
UDTLinger linger = new UDTLinger();
linger.OnOff = ((LingerOption)optionValue).Enabled ? ((short)1) : ((short)0);
linger.Time = (short)((LingerOption)optionValue).LingerTime;
size = Marshal.SizeOf(typeof(UDTLinger));
optionValue = linger;*/
return;
}
else throw new NotImplementedException();
try
{
API_Setsockopt(_handle, (int)optionLevel, optionName, ref optionValue, size);
}
catch (Exception e)
{
Console.Write(e.Message);
}
//API_Setsockopt(int handle, int level, UDTOption option, ref int optionValue /*const void* optval*/, int optlen);
#endif
}
#endregion
#region Properties
public bool Connected
{
get
{
#if UDT_FULLTCP
return _tcpSocket.Connected;
#else
if (_handle < 0)
return false;
return API_IsConnected(_handle);
#endif
}
}
public EndPoint LocalEndPoint
{
get
{
#if UDT_FULLTCP
return _tcpSocket.LocalEndPoint;
#else
return _localEndPoint;
#endif
}
}
public EndPoint RemoteEndPoint
{
get
{
#if UDT_FULLTCP
return _tcpSocket.RemoteEndPoint;
#else
return _remoteEndPoint;
#endif
}
}
public int Handle
{
get
{
#if UDT_FULLTCP
return _tcpSocket.Handle.ToInt32();
#else
return _handle;
#endif
}
}
private bool IsAsynchronous
{
get
{
throw new NotImplementedException();
}
set
{
//API_SetAsynchronous(_handle, value);
}
}
#endregion
#region Options
public int SendTimeOut
{
get
{
throw new NotImplementedException();
}
set
{
SetSocketOption(SocketOptionLevel.IP, UDTSocketOptionName.UDT_SNDTIMEO, value);
//API_Setsockopt(this._handle, 0, (int)UDTOption.UDT_SNDTIMEO, ref (object)value, 4);
}
}
public int ReceiveTimeOut
{
get
{
throw new NotImplementedException();
}
set
{
SetSocketOption(SocketOptionLevel.IP, UDTSocketOptionName.UDT_RCVTIMEO, value);
//API_Setsockopt(this._handle, 0, (int)UDTOption.UDT_RCVTIMEO, ref (object)value, 4);
}
}
#endregion
#region DEBUG...
[System.Diagnostics.Conditional("UDT_TRACE")]
static private void UDTTrace(string message)
{
Console.WriteLine(message);
}
#endregion
}
#region UDTSocketOptionName
public enum UDTSocketOptionName
{
UDT_MSS = 0, // the Maximum Transfer Unit
UDT_SNDSYN = 1, // if sending is blocking
UDT_RCVSYN = 2, // if receiving is blocking
UDT_CC = 3, // custom congestion control algorithm
UDT_FC = 4, // deprecated, for compatibility only
UDT_SNDBUF = 5, // maximum buffer in sending queue
UDT_RCVBUF = 6, // UDT receiving buffer size
UDT_LINGER = 7, // waiting for unsent data when closing
UDP_SNDBUF = 8, // UDP sending buffer size
UDP_RCVBUF = 9, // UDP receiving buffer size
UDT_MAXMSG = 10, // maximum datagram message size
UDT_MSGTTL = 11, // time-to-live of a datagram message
UDT_RENDEZVOUS = 12, // rendezvous connection mode
UDT_SNDTIMEO = 13, // send() timeout
UDT_RCVTIMEO = 14 // recv() timeout
}
#endregion
#region UDTAsyncResult
public sealed class UDTAsyncResult : IAsyncResult
{
internal object _stateObject;
internal int _size;
internal UDTSocket _socket;
internal int _overlappedIoHanlde;
internal UDTSocketException Exception;
public UDTAsyncResult(int size, object stateObject, UDTSocket socket, int overlappedIoHanlde)
{
_size = size;
_stateObject = stateObject;
_socket = socket;
_overlappedIoHanlde = overlappedIoHanlde;
}
public UDTAsyncResult(int size, object stateObject)
{
_size = size;
_stateObject = stateObject;
}
// Summary:
// Gets a System.Threading.WaitHandle that is used to wait for an asynchronous
// operation to complete.
//
// Returns:
// A System.Threading.WaitHandle that is used to wait for an asynchronous operation
// to complete.
public WaitHandle AsyncWaitHandle
{
get { return null; }
}
// Summary:
// Gets an indication of whether the asynchronous operation completed synchronously.
//
// Returns:
// true if the asynchronous operation completed synchronously; otherwise, false.
public bool CompletedSynchronously
{
get { return true; }
}
// Summary:
// Gets an indication whether the asynchronous operation has completed.
//
// Returns:
// true if the operation is complete; otherwise, false.
public bool IsCompleted
{
get { return true; }
}
// Summary:
// Gets a user-defined object that qualifies or contains information about an
// asynchronous operation.
//
// Returns:
// A user-defined object that qualifies or contains information about an asynchronous
// operation.
public object AsyncState
{
get { return _stateObject; }
}
}
#endregion
#region UDTSocketException
public sealed class UDTSocketException : Exception
{
private int _errorCode;
public UDTSocketException(int errorCode, string errorMessage)
: base(errorMessage)
{
_errorCode = errorCode;
}
public UDTSocketException()
: base(API_GetLastErrorMessage())
{
_errorCode = API_GetLastErrorCode();
}
public int ErrorCode
{
get
{
return _errorCode;
}
set { _errorCode = value; }
}
[DllImport("transport.dll", EntryPoint = "UDTGetlasterrorCode")]
private static extern int API_GetLastErrorCode();
[DllImport("transport.dll", EntryPoint = "UDTGetlasterrorMessage")]
private static extern string API_GetLastErrorMessage();
}
#endregion
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -