📄 udtsocket.cs
字号:
namespace NCindy.Protocol.UDT
{
using NCindy.CommandProcessor;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;
public sealed class UDTSocket
{
private static List<AsyncAcceptRegistration> _acceptRegistrations = new List<AsyncAcceptRegistration>(100);
private int _handle;
private IPEndPoint _localEndPoint;
internal static NCindy.CommandProcessor.CommandProcessor _processor = new NCindy.CommandProcessor.CommandProcessor("UDT");
private static List<AsyncReceiveRegistration> _receiveRegistrations = new List<AsyncReceiveRegistration>(100);
private IPEndPoint _remoteEndPoint;
private SocketType _socketType;
private static Thread _udtThreadProcessing;
public object Tag;
private static int UDT_ERROR = -1;
private static int UDT_INVALID_SOCK = -1;
private static EndOperationHandler udtEndSendCallback;
static UDTSocket()
{
AppDomain.CurrentDomain.ProcessExit += new EventHandler(UDTSocket.CurrentDomain_ProcessExit);
udtEndSendCallback = new EndOperationHandler(UDTSocket.UDTEndSendCallback);
GC.KeepAlive(udtEndSendCallback);
API_SetUDTEndSendCallback(udtEndSendCallback);
_processor.Start();
_udtThreadProcessing = new Thread(new ThreadStart(UDTSocket.UDTThreadProcessing));
_udtThreadProcessing.IsBackground = true;
_udtThreadProcessing.Name = "UDTThread Select Processing";
_udtThreadProcessing.Start();
}
public UDTSocket(AddressFamily addressFamily) : this(addressFamily, SocketType.Stream)
{
}
public UDTSocket(AddressFamily addressFamily, SocketType socketType)
{
this._handle = -1;
this._socketType = socketType;
this._handle = API_UDTSocket((int) addressFamily, (int) this._socketType, 0);
this.IsAsynchronous = true;
}
private UDTSocket(int handle, SocketType socketType, IPEndPoint remoteEndPoint, IPEndPoint localEndPoint)
{
this._handle = -1;
this._socketType = socketType;
this._handle = handle;
this._remoteEndPoint = remoteEndPoint;
this._localEndPoint = localEndPoint;
this.IsAsynchronous = true;
}
public UDTSocket Accept()
{
IPEndPoint remoteEndPoint;
IPEndPoint point3;
EndPoint point = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
SocketAddress socketAddress = ((IPEndPoint) point).Serialize();
byte[] name = new byte[socketAddress.Size];
for (int i = 0; i < socketAddress.Size; i++)
{
name[i] = socketAddress[i];
}
int namelen = 0;
int handle = API_Accept(this._handle, name, out namelen);
if (UDT_INVALID_SOCK == handle)
{
throw new UDTSocketException(API_GetLastErrorCode(), API_GetLastErrorMessage());
}
for (int j = 0; j < socketAddress.Size; j++)
{
socketAddress[j] = name[j];
}
if (socketAddress.Family == AddressFamily.InterNetwork)
{
remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
}
else
{
remoteEndPoint = new IPEndPoint(IPAddress.IPv6Any, 0);
}
remoteEndPoint = (IPEndPoint) remoteEndPoint.Create(socketAddress);
namelen = socketAddress.Size;
if (UDT_ERROR == API_Getpeername(handle, name, out namelen))
{
throw new UDTSocketException(API_GetLastErrorCode(), API_GetLastErrorMessage());
}
if (socketAddress.Family == AddressFamily.InterNetwork)
{
point3 = new IPEndPoint(IPAddress.Any, 0);
}
else
{
point3 = new IPEndPoint(IPAddress.IPv6Any, 0);
}
return new UDTSocket(handle, this._socketType, remoteEndPoint, (IPEndPoint) point3.Create(socketAddress));
}
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTAccept")]
private static extern int API_Accept(int handle, byte[] name, out int namelen);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTBeginSend")]
private static extern int API_BeginSend(int handle, byte[] buffer, int len, int flags, IntPtr context);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTBind")]
private static extern int API_Bind(int handle, byte[] name, int namelen);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTClose")]
private static extern int API_Close(int handle);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTGetlasterrorCode")]
private static extern int API_GetLastErrorCode();
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTGetlasterrorMessage")]
private static extern string API_GetLastErrorMessage();
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTGetpeername")]
private static extern int API_Getpeername(int handle, byte[] name, out int namelen);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTGetsockopt")]
private static extern int API_Getsockopt(int handle, int level, UDTSocketOptionName option, ref object optionValue, int optlen);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTIsConnected")]
private static extern bool API_IsConnected(int handle);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTIsOnAccept")]
private static extern bool API_IsOnAccept(int handle);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTIsOnError")]
private static extern bool API_IsOnError(int handle);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTIsOnRead")]
private static extern bool API_IsOnRead(int handle);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTIsOnWrite")]
private static extern bool API_IsOnWrite(int handle);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTListen")]
private static extern int API_Listen(int handle, int backlog);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTRecv")]
private static extern int API_Receive(int handle, byte[] buffer, int offset, int len, int flags);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTRecvmsg")]
private static extern int API_Recvmsg(int handle, byte[] buffer, int offset, int len);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTSelect")]
private static extern int API_Select([In] int ignoredParameter, [In, Out] IntPtr[] readfds, [In, Out] IntPtr[] writefds, [In, Out] IntPtr[] exceptfds, [In] ref TimeValue timeout);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTSend")]
private static extern int API_Send(int handle, byte[] buffer, int len, int flags);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTSendmsg")]
private static extern int API_Sendmsg(int handle, byte[] buffer, int len, int ttl, bool inorder);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTSetAsynchronous")]
private static extern int API_SetAsynchronous(int handle, bool isAsynchronous);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTSetsockopt")]
private static extern int API_Setsockopt(int handle, int level, UDTSocketOptionName option, ref object optionValue, int optlen);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTSetEndSendCallback")]
private static extern int API_SetUDTEndSendCallback([MarshalAs(UnmanagedType.FunctionPtr)] EndOperationHandler callback);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTShutdown")]
private static extern int API_Shutdown(int handle, int how);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTConnect")]
private static extern int API_UDTConnect(int handle, byte[] name, int namelen);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTSelect")]
private static extern int API_UDTSelect(int[] readfds, int readCount, int[] writefds, int writeCount, int[] exceptfds, int timeoutMicroseconds);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTSocket")]
private static extern int API_UDTSocket(int af, int type, int protocol);
[SuppressUnmanagedCodeSecurity, DllImport("transport.dll", EntryPoint="UDTWaitForEvent")]
private static extern void API_WaitForEvent();
public IAsyncResult BeginAccept(AsyncCallback callback, object state)
{
AsyncAcceptRegistration registration = new AsyncAcceptRegistration(this, callback, state);
lock (_acceptRegistrations)
{
_acceptRegistrations.Add(registration);
}
return null;
}
public IAsyncResult BeginConnect(IPEndPoint endPoint, AsyncCallback callback, object state)
{
AsyncConnectRegistration command = new AsyncConnectRegistration(this, endPoint, callback, state);
_processor.AddCommand(command);
return null;
}
public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state)
{
AsyncReceiveRegistration registration = new AsyncReceiveRegistration(this, buffer, offset, size, socketFlags, callback, state);
lock (_receiveRegistrations)
{
_receiveRegistrations.Add(registration);
}
return null;
}
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state)
{
AsyncSendRegistration registration = new AsyncSendRegistration(this, buffer, offset, size, socketFlags, callback, state);
IntPtr context = GCHandle.ToIntPtr(GCHandle.Alloc(registration));
if (UDT_ERROR == API_BeginSend(this._handle, buffer, size, (int) socketFlags, context))
{
throw new UDTSocketException();
}
_processor.AddCommand(registration);
return null;
}
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError error, AsyncCallback callback, object state)
{
error = 0;
try
{
return this.BeginSend(buffer, offset, size, socketFlags, callback, state);
}
catch (Exception)
{
error = -1;
return null;
}
}
public void Bind(EndPoint localEP)
{
this._localEndPoint = (IPEndPoint) localEP;
SocketAddress address = ((IPEndPoint) localEP).Serialize();
byte[] name = new byte[address.Size];
for (int i = 0; i < address.Size; i++)
{
name[i] = address[i];
}
if (UDT_ERROR == API_Bind(this._handle, name, address.Size))
{
throw new UDTSocketException();
}
}
public void Close()
{
API_Close(this._handle);
this._handle = -1;
}
public void Connect(EndPoint remoteEP)
{
SocketAddress address = ((IPEndPoint) remoteEP).Serialize();
byte[] name = new byte[address.Size];
for (int i = 0; i < address.Size; i++)
{
name[i] = address[i];
}
if (UDT_ERROR == API_UDTConnect(this._handle, name, address.Size))
{
throw new UDTSocketException();
}
}
private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
ShutDownUDT();
}
public UDTSocket EndAccept(IAsyncResult ar)
{
return ((UDTAsyncResult) ar)._socket;
}
public void EndConnect(IAsyncResult ar)
{
if (((UDTAsyncResult) ar).Exception != null)
{
throw ((UDTAsyncResult) ar).Exception;
}
}
public int EndReceive(IAsyncResult ar)
{
return ((UDTAsyncResult) ar)._size;
}
public int EndSend(IAsyncResult ar)
{
return ((UDTAsyncResult) ar)._size;
}
public void Listen(int backlog)
{
if (UDT_ERROR == API_Listen(this._handle, backlog))
{
throw new UDTSocketException();
}
}
public bool Poll(int timeOutMicroSeconds, SelectMode mode)
{
switch (mode)
{
case SelectMode.SelectRead:
{
int[] readHandles = new int[] { this.Handle };
int[] writeHandles = new int[0];
int[] exceptionHandles = new int[0];
Select(readHandles, writeHandles, exceptionHandles, timeOutMicroSeconds);
return (readHandles[0] == this.Handle);
}
case SelectMode.SelectWrite:
{
int[] numArray4 = new int[0];
int[] numArray5 = new int[] { this.Handle };
int[] numArray6 = new int[0];
Select(numArray4, numArray5, numArray6, timeOutMicroSeconds);
return (numArray5[0] == this.Handle);
}
case SelectMode.SelectError:
{
int[] numArray7 = new int[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -