C#调用UDT

UDT 简介

   参考 http://baike.baidu.com/view/1036563.htm

UDT C++源码

   http://udt.sourceforge.net/

UDT c# 调用导出

// UDTLibary.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#ifndef WIN32
#include <cstdlib>
#include <cstring>
#include <netdb.h>
#include <signal.h>
#include <unistd.h>
#else
#include <winsock2.h>
#include <ws2tcpip.h>
#include <wspiapi.h>
#endif
#include <algorithm>
#include <iostream>

#include "udt.h"
using namespace std;
struct RemoteEndPoint
{
public:
	USHORT port;
	char* ip;
};
extern "C" __declspec(dllexport)
	int StartUp()
{
	return UDT::startup();
};
extern "C" __declspec(dllexport)
	int CleanUp()
{
	return UDT::cleanup();
};
extern "C" __declspec(dllexport)
	UDTSOCKET NewSocket(int family, int socktype, int protocol)
{
	return UDT::socket(family,socktype,protocol);
}
extern "C" __declspec(dllexport)
	int BindSocket(UDTSOCKET u,UDPSOCKET udpsockt)
{
	return UDT::bind(u,udpsockt);
}
extern "C" __declspec(dllexport)
	int Bind(UDTSOCKET usock,int family,int sockType,char*ip ,int port)
{
	addrinfo hints;
	addrinfo* res;
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_flags = AI_PASSIVE;
	hints.ai_family = family;
	hints.ai_socktype = sockType;
	char service[16];
	sprintf(service, "%d", port);

	if (0 != getaddrinfo(ip, service, &hints, &res))
	{
		return -1;
	}
	if (UDT::ERROR == UDT::bind(usock, res->ai_addr, res->ai_addrlen))
	{
		return -1;
	}
	freeaddrinfo(res);
	return 0;
}

extern "C" __declspec(dllexport)
	int Listen(UDTSOCKET usock, int backlog)
{
	return UDT::listen(usock,backlog);
}
extern "C" __declspec(dllexport)
	UDTSOCKET Accept(UDTSOCKET usock,char* remoteip,int* iplen,int* port)
{
	sockaddr_storage clientaddr;
	int addrlen = sizeof(clientaddr);

	UDTSOCKET sock=  UDT::accept(usock, (sockaddr*)&clientaddr, &addrlen);
	sockaddr_in* addr= (sockaddr_in*)&clientaddr;
	*port=addr->sin_port;
	char* ip=inet_ntoa(addr->sin_addr);
	*iplen=strlen(ip);
	memcpy(remoteip,ip,*iplen);
	return sock;
}
extern "C" __declspec(dllexport)
	int GetSockName(UDTSOCKET usock,char* remoteip,int* iplen,int* port)
{
	struct sockaddr_in sa;   ;
	int namelen=sizeof(sa);
	if(UDT::getsockname(usock,(struct sockaddr FAR *)&sa,&namelen)==0)
	{
		*port=sa.sin_port;
		char* ip=inet_ntoa(sa.sin_addr);
		*iplen=strlen(ip);
		memcpy(remoteip,ip,*iplen);
		return 0;
	}
	else
	{
		return -1;
	}
};
extern "C" __declspec(dllexport)
	int GetSockPeerName(UDTSOCKET usock,char* remoteip,int* iplen,int* port)
{
	struct sockaddr_in sa;   ;
	int namelen=sizeof(sa);
	if(UDT::getpeername(usock,(struct sockaddr FAR *)&sa,&namelen)==0)
	{
		*port=sa.sin_port;
		char* ip=inet_ntoa(sa.sin_addr);
		*iplen=strlen(ip);
		memcpy(remoteip,ip,*iplen);
		return 0;
	}
	else
	{
		return -1;
	}
};
extern "C" __declspec(dllexport)
	int Connect(UDTSOCKET usock,int family,int sockType,char* ip,int port)
{
	addrinfo hints;
	addrinfo* res;

	memset(&hints, 0, sizeof(struct addrinfo));

	hints.ai_flags = AI_PASSIVE;
	hints.ai_family = family;
	hints.ai_socktype = sockType;
	char service[16];
	sprintf(service, "%d", port);

	if (0 != getaddrinfo(ip, service, &hints, &res))
	{
		return -1;
	}
	if (UDT::ERROR == UDT::connect(usock, res->ai_addr, res->ai_addrlen))
	{
		return -1;
	}
	freeaddrinfo(res);
	return 0;
};

extern "C" __declspec(dllexport)
	int Close(UDTSOCKET usock)
{
	return UDT::close(usock);
}
extern "C" __declspec(dllexport)
	int Send(UDTSOCKET usock , char* buffer,int len)
{
	int offset=0;
	int sendLen=0;
SendRetry:
	sendLen= UDT::send(usock,&buffer[offset],len-offset,0);
	if(sendLen<0) return sendLen;
	offset+=sendLen;
	if(offset<len)
	{
		goto SendRetry;
	}
	else if(offset>len)
	{
		return -1;
	}
	return offset;
};
extern "C" __declspec(dllexport)
	int Receive(UDTSOCKET usock , char* buffer,int len)
{
	return UDT::recv(usock,buffer,len,0);
};
extern "C" __declspec(dllexport)
	int Perfmon(UDTSOCKET u, CPerfMon* perf, bool clear)
{
	return UDT::perfmon(u, perf, clear);
}
extern "C" __declspec(dllexport)
	int GetSocketOption(UDTSOCKET u, int level, UDT::SOCKOPT optname, void* optval, int* optlen)
{
	return UDT::getsockopt(u, level, optname, optval, optlen);
}
extern "C" __declspec(dllexport)
	int SetSocketOption(UDTSOCKET u, int level, UDT::SOCKOPT optname, const void* optval, int optlen)
{
	return UDT::setsockopt(u, level, optname, optval, optlen);
}
extern "C" __declspec(dllexport)
	UDTSTATUS GetSocketState(UDTSOCKET u)
{
	return UDT::getsockstate(u);
}
extern "C" __declspec(dllexport)
	int64_t SendFile(UDTSOCKET u, fstream& ifs, int64_t& offset, int64_t size, int block)
{
	return UDT::sendfile(u,ifs,offset,size,block);
}
extern "C" __declspec(dllexport)
	int64_t RecvFile(UDTSOCKET u, fstream& ofs, int64_t& offset, int64_t size, int block)
{
	return UDT::recvfile(u, ofs, offset, size, block);
}
extern "C" __declspec(dllexport)
	int GetErrorCode()
{
	return UDT::getlasterror().getErrorCode();
}
extern "C" __declspec(dllexport)
	void GetErrorMessage(char* str,int  len, int* errLen,int* errorCode)
{
	CUDTException err=UDT::getlasterror();
	*errorCode=err.getErrorCode();
	const char* errMsg= err.getErrorMessage();
	int msgLen=strlen(errMsg);
	if(msgLen<=  len)
	{
		memcpy(str,errMsg,msgLen);
	}
	else
	{
		memcpy(str,errMsg, len);
	}
	*errLen=msgLen;
}
extern "C" __declspec(dllexport)
	int Select(int nfds,UDTSOCKET* read,int*readlen,UDTSOCKET*write,int*writelen,UDTSOCKET*except,int*exceptlen,const struct timeval* timeout)
{
	UDT::UDSET readfds;
	UDTSOCKET* tempRead=read;
	for(int i=0;i<*readlen;i++)
	{
		readfds.insert(*tempRead++ );
	}
	UDT::UDSET writefds;
	UDTSOCKET* tempWrite=write;
	for(int i=0;i<*writelen;i++)
	{
		writefds.insert(*tempWrite++);
	}
	UDT::UDSET exceptfds;
	UDTSOCKET* tempExcept=except;
	for(int i=0;i<*exceptlen;i++)
	{
		exceptfds.insert(*tempExcept++);
	}
	int result=UDT::select(nfds,&readfds,&writefds,&exceptfds,timeout);
	*readlen=readfds.size();
	*writelen=writefds.size();
	*exceptlen=exceptfds.size();
	set<UDTSOCKET>::reverse_iterator readrit;
	for(readrit=readfds.rbegin();readrit!=readfds.rend();readrit++)
	{
		*read++=*readrit;
	}
	set<UDTSOCKET>::reverse_iterator writerit;
	for(writerit=writefds.rbegin();writerit!=writefds.rend();writerit++)
	{
		*write++=*writerit;
	}
	set<UDTSOCKET>::reverse_iterator exceptrit;
	for(exceptrit=exceptfds.rbegin();exceptrit!=exceptfds.rend();exceptrit++)
	{
		*except++=*exceptrit;
	}
	return result;
}


 

C#封装方法

 CPerfMon.cs

    public struct CPerfMon
    {
        // global measurements
        public long msTimeStamp;                 // time since the UDT entity is started, in milliseconds

        public long pktSentTotal;                // total number of sent data packets, including retransmissions
        public long pktRecvTotal;                // total number of received packets
        public int pktSndLossTotal;                 // total number of lost packets (sender side)
        public int pktRcvLossTotal;                 // total number of lost packets (receiver side)
        public int pktRetransTotal;                 // total number of retransmitted packets
        public int pktSentACKTotal;                 // total number of sent ACK packets
        public int pktRecvACKTotal;                 // total number of received ACK packets
        public int pktSentNAKTotal;                 // total number of sent NAK packets
        public int pktRecvNAKTotal;                 // total number of received NAK packets
        public long usSndDurationTotal;		// total time duration when UDT is sending data (idle time exclusive)

        // local measurements
        public long pktSent;                     // number of sent data packets, including retransmissions

        public long pktRecv;                     // number of received packets
        public int pktSndLoss;                      // number of lost packets (sender side)
        public int pktRcvLoss;                      // number of lost packets (receiver side)
        public int pktRetrans;                      // number of retransmitted packets
        public int pktSentACK;                      // number of sent ACK packets
        public int pktRecvACK;                      // number of received ACK packets
        public int pktSentNAK;                      // number of sent NAK packets
        public int pktRecvNAK;                      // number of received NAK packets
        public double mbpsSendRate;                 // sending rate in Mb/s
        public double mbpsRecvRate;                 // receiving rate in Mb/s
        public long usSndDuration;		// busy sending time (i.e., idle time exclusive)

        // instant measurements
        public double usPktSndPeriod;               // packet sending period, in microseconds

        public int pktFlowWindow;                   // flow window size, in number of packets
        public int pktCongestionWindow;             // congestion window size, in number of packets
        public int pktFlightSize;                   // number of packets on flight
        public double msRTT;                        // RTT, in milliseconds
        public double mbpsBandwidth;                // estimated bandwidth, in Mb/s
        public int byteAvailSndBuf;                 // available UDT sender buffer size
        public int byteAvailRcvBuf;                 // available UDT receiver buffer size
    }


 

SOCKOPT.cs

    public enum SOCKOPT
    {
        /// <summary>
        /// 最大传输单位
        /// </summary>
        UDT_MSS,
        /// <summary>
        /// 是否阻塞发送
        /// </summary>
        UDT_SNDSYN,
        /// <summary>
        /// 是否阻塞接收
        /// </summary>
        UDT_RCVSYN,
        /// <summary>
        /// 自定义拥塞控制算法
        /// </summary>
        UDT_CC,
        /// <summary>
        /// 窗口大小
        /// </summary>
        UDT_FC,
        /// <summary>
        /// 发送队列缓冲最大值
        /// </summary>
        UDT_SNDBUF,
        /// <summary>
        /// UDT接收缓冲大小
        /// </summary>
        UDT_RCVBUF,
        /// <summary>
        /// 关闭时等待数据发送完成
        /// </summary>
        UDT_LINGER,
        /// <summary>
        /// UDP发送缓冲大小
        /// </summary>
        UDP_SNDBUF,
        /// <summary>
        /// UDP接收缓冲大小
        /// </summary>
        UDP_RCVBUF,
        /// <summary>
        /// maximum datagram message size
        /// </summary>
        UDT_MAXMSG,
        /// <summary>
        /// time-to-live of a datagram message
        /// </summary>
        UDT_MSGTTL,
        /// <summary>
        /// 会合连接模式
        /// </summary>
        UDT_RENDEZVOUS,
        /// <summary>
        /// send()超时
        /// </summary>
        UDT_SNDTIMEO,
        /// <summary>
        /// recv()超时
        /// </summary>
        UDT_RCVTIMEO,
        /// <summary>
        /// 复用一个已存在的端口或者创建一个新的端口
        /// </summary>
        UDT_REUSEADDR,
        /// <summary>
        ///  当前连接可以使用的最大带宽(bytes per second)
        /// </summary>
        UDT_MAXBW,
        /// <summary>
        /// current socket state, see UDTSTATUS, read only
        /// </summary>
        UDT_STATE,
        /// <summary>
        /// current avalable events associated with the socket
        /// </summary>
        UDT_EVENT
    };


UDTSTATUS.cs

    public enum UDTSTATUS
    {
        INIT = 1,
        OPENED,
        LISTENING,
        CONNECTING,
        CONNECTED,
        BROKEN,
        CLOSING,
        CLOSED,
        NONEXIST
    }


UDTException.cs

    public class UDTException : Exception
    {
        public int ErrorCode { get; private set; }

        public UDTException(string message, int errorCode)
            : base(message)
        {
            this.ErrorCode = errorCode;
        }

        public UDTException(int errorCode)
        {
            this.ErrorCode = errorCode;
        }

        public override string ToString()
        {
            return string.Format("ErrorCode={0},Exception:{0}", base.ToString());
        }
    }


NativeUDT.cs


    

    internal static class NativeUDT
    {
        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int StartUp();

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int CleanUp();

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr NewSocket(AddressFamily family, SocketType socktype, ProtocolType protocol);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int BindSocket(IntPtr udtSocket, IntPtr udpsockHandle);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int BindSocket(IntPtr udtSocket, Socket udpsockHandle);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Bind(IntPtr udtSocket, AddressFamily family, SocketType sockType, string ip, int port);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Listen(IntPtr udtSocket, int backlog);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        unsafe public static extern IntPtr Accept(IntPtr udtSocket, byte* ip, ref int iplen, ref int port);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        unsafe public static extern int GetSockName(IntPtr usock, byte* remoteip, ref int iplen, ref int port);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        unsafe public static extern int GetSockPeerName(IntPtr usock, byte* remoteip, ref int iplen, ref int port);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Connect(IntPtr udtSocket, AddressFamily family, SocketType sockType, string ip, int port);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Close(IntPtr udtSocket);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int GetSocketOption(IntPtr udtSocket, int level, SOCKOPT optname, IntPtr optval, ref int optlen);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SetSocketOption(IntPtr udtSocket, int level, SOCKOPT optname, IntPtr optval, int optlen);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SetSocketOption(IntPtr udtSocket, int level, SOCKOPT optname, ref int optval, int optlen);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int SetSocketOption(IntPtr udtSocket, int level, SOCKOPT optname, ref bool optval, int optlen);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Send(IntPtr udtSocket, IntPtr buf, int len);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        unsafe public static extern int Send(IntPtr udtSocket, byte* buf, int len);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Receive(IntPtr udtSocket, IntPtr buf, int len);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        unsafe public static extern int Receive(IntPtr udtSocket, byte* buf, int len);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Perfmon(IntPtr udtSocket, ref CPerfMon perf, bool clear);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern UDTSTATUS GetSocketState(IntPtr udtSocket);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern int GetErrorCode();

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        public static extern void GetErrorMessage(StringBuilder errorMsg, int len, ref int errorlen, ref  int errorCode);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, SetLastError = true), SuppressUnmanagedCodeSecurity()]
        public static extern int Select([In]int nfds, [In, Out]IntPtr[] readfds, ref int readLen, [In, Out]IntPtr[] writefds, ref int writeLen, [In, Out]IntPtr[] exceptfds, ref int exceptLen, [In]IntPtr timeoutMicroseconds);

        [DllImport("UDTLibary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, SetLastError = true), SuppressUnmanagedCodeSecurity()]
        public static extern int Select([In]int nfds, [In, Out]IntPtr[] readfds, ref int readLen, [In, Out]IntPtr[] writefds, ref int writeLen, [In, Out]IntPtr[] exceptfds, ref int exceptLen, [In]ref TimeValue timeoutMicroseconds);
    }


TimeValue.cs

[StructLayout(LayoutKind.Sequential)]
    internal struct TimeValue
    {
        public int Seconds;
        public int Microseconds;
    }

UDTSocket.cs

    /// <summary>
    /// UDTSocket
    /// </summary>
    /// <example>
    /// <![CDATA[
    /// private UDTSocket CreateSocket(string ip = "0.0.0.0", int port = 0, bool rendezvous = false)
    /// {
    ///    UDTSocket sock = new UDTSocket();
    ///    int snd_buf = 64000;
    ///    int rcv_buf = 64000;
    ///    sock.SetSocketOption(SOCKOPT.UDT_SNDBUF, snd_buf);
    ///    sock.SetSocketOption(SOCKOPT.UDT_RCVBUF, rcv_buf);
    ///    sock.SetSocketOption(SOCKOPT.UDP_SNDBUF, snd_buf);
    ///    sock.SetSocketOption(SOCKOPT.UDP_RCVBUF, rcv_buf);
    ///    int fc = 64;
    ///    sock.SetSocketOption(SOCKOPT.UDT_FC, fc);
    ///    bool reuse = true;
    ///    sock.SetSocketOption(SOCKOPT.UDT_REUSEADDR, reuse);
    ///    sock.SetSocketOption(SOCKOPT.UDT_RENDEZVOUS, rendezvous);
    ///    sock.SetSocketOption(SOCKOPT.UDT_MSS, (int)this.numMTU.Value);
    ///    sock.SetSocketOption(SOCKOPT.UDT_SNDSYN, this.ckSendSyn.Checked);
    ///    sock.SetSocketOption(SOCKOPT.UDT_RCVSYN, this.ckReviceSyn.Checked);
    ///   sock.Bind("0.0.0.0", port);
    ///    return sock;
    /// }
    /// ]]>
    /// </example>
    /// <remarks>绑定现有Socket时使用void Bind(Socket socket)方法。</remarks>
    public sealed class UDTSocket : Collect
    {
        private static readonly TracingImpl Tracing = TracingManager.GetTracing(typeof(UDTSocket));

        /// <summary>
        /// 获取UDT本地监听地址
        /// </summary>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        unsafe public IPEndPoint LocalEndPoint
        {
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                int port = 0;
                byte[] ip = new byte[15];
                fixed (byte* ptr = ip)
                {
                    int iplen = 0;
                    if (NativeUDT.GetSockName(this.Handle, ptr, ref iplen, ref port) != 0)
                    {
                        return null;
                    }
                    else
                    {
                        return new IPEndPoint(IPAddress.Parse(Encoding.Default.GetString(ip, 0, iplen)), port);
                    }
                }
            }
        }

        /// <summary>
        /// 获取UDT远程地址
        /// </summary>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        unsafe public IPEndPoint RmoteEndPoint
        {
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                int port = 0;
                byte[] ip = new byte[15];
                fixed (byte* ptr = ip)
                {
                    int iplen = 0;
                    if (NativeUDT.GetSockPeerName(this.Handle, ptr, ref iplen, ref port) != 0)
                    {
                        return null;
                    }
                    else
                    {
                        return new IPEndPoint(IPAddress.Parse(Encoding.Default.GetString(ip, 0, iplen)), port);
                    }
                }
            }
        }

        /// <summary>
        /// 当前UDT句柄
        /// </summary>
        public IntPtr Handle
        {
            get;
            private set;
        }

        static UDTSocket()
        {
            NativeUDT.StartUp();
            //AppDomain.CurrentDomain.ProcessExit += delegate
            //{
            //    NativeUDT.CleanUp();
            //};
        }

        ~UDTSocket()
        {
            this.Dispose();
        }

        public AddressFamily Family { get; private set; }

        public SocketType SocketType { get; private set; }

        public UDTSocket()
            : this(AddressFamily.InterNetwork, SocketType.Stream)
        {
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="family"></param>
        /// <param name="sockType"></param>
        /// <remarks>SocketType目前只实现了Stream形式</remarks>
        public UDTSocket(AddressFamily family, SocketType sockType)
        {
            // SOCK_STREAM: 提供面向连接的稳定数据传输,即TCP协议。
            // SOCK_DGRAM: 使用不连续不可靠的数据包连接。
            // SOCK_PACKET: 与网络驱动程序直接通信。
            // 注:此处的SOCK_STREAM并不是表示UDT将会使用TCP类型的Socket,在底层将会转化为UDT_STREAM
            // 并且在UDT中仅支持SOCK_STREAM和SOCK_DGRAM,分别对应UDT_STREAM和UDT_DGRAM
            // 此处实际上最终调用了CUDTUnited的newSocket,第一个参数会被直接设置到CUDT的m_iIPversion,第二个参数会被映射为UDT的连接类型,第三个参数被忽略,没有实际意义
            this.Handle = NativeUDT.NewSocket(family, sockType, (ProtocolType)0);
            if (this.Handle == IntPtr.Zero)
            {
                throw GetUDTException();
            }
            this.Family = family;
            this.SocketType = sockType;
        }

        /// <summary>
        /// 获取当前UDT状态
        /// </summary>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public UDTSTATUS State
        {
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                return NativeUDT.GetSocketState(this.Handle);
            }
        }

        /// <summary>
        /// 获取UDT性能相关数据
        /// </summary>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public CPerfMon Perfmon
        {
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                CPerfMon perfmon = new CPerfMon();
                NativeUDT.Perfmon(this.Handle, ref perfmon, false);
                return perfmon;
            }
        }

        /// <summary>
        /// 最大传输带宽
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public int MaxBandWith
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                this.SetSocketOption(SOCKOPT.UDT_MAXBW, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(4);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_MAXBW, ptr, 4);
                    return Marshal.ReadInt32(ptr);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// UDT发送缓冲区队列大小
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ArgumentException">vlaue must be >=1</exception>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public int UDTSendBufferSize
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                if (value < 1) throw new ArgumentException();
                this.SetSocketOption(SOCKOPT.UDT_SNDBUF, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(4);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_SNDBUF, ptr, 4);
                    return Marshal.ReadInt32(ptr);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// UDT接收缓冲区队列大小
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ArgumentException">vlaue must be >=1</exception>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public int UDTReviceBufferSize
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                if (value < 0) throw new ArgumentException();
                this.SetSocketOption(SOCKOPT.UDT_RCVBUF, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(4);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_RCVBUF, ptr, 4);
                    return Marshal.ReadInt32(ptr);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// UDP发送缓冲区队列大小
        /// </summary>
        /// <exception cref="ArgumentException">vlaue must be >=1</exception>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public int UDPSendBufferSize
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                if (value < 0) throw new ArgumentException();
                this.SetSocketOption(SOCKOPT.UDP_SNDBUF, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(4);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDP_SNDBUF, ptr, 4);
                    return Marshal.ReadInt32(ptr);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// UDP接收缓冲区队列大小
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ArgumentException">vlaue must be >=1</exception>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public int UDPReviceBufferSize
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                if (value < 0) throw new ArgumentException();
                this.SetSocketOption(SOCKOPT.UDP_RCVBUF, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(4);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDP_RCVBUF, ptr, 4);
                    return Marshal.ReadInt32(ptr);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// 窗口大小
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ArgumentException">vlaue must be >=1</exception>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public int WindowSize
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                if (value < 0) throw new ArgumentException();
                this.SetSocketOption(SOCKOPT.UDT_FC, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(4);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_FC, ptr, 4);
                    return Marshal.ReadInt32(ptr);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// 最大传输单元
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ArgumentException">vlaue must be >=1</exception>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public int MSS
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                if (value < 0) throw new ArgumentException();
                this.SetSocketOption(SOCKOPT.UDT_MSS, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(4);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_MSS, ptr, 4);
                    return Marshal.ReadInt32(ptr);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// 发送超时时间
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public int SendTimeOut
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                this.SetSocketOption(SOCKOPT.UDT_SNDTIMEO, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(4);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_SNDTIMEO, ptr, 4);
                    return Marshal.ReadInt32(ptr);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// 接收超时时间
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public int ReviceTimeOut
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                this.SetSocketOption(SOCKOPT.UDT_RCVTIMEO, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(4);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_RCVTIMEO, ptr, 4);
                    return Marshal.ReadInt32(ptr);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// 是否汇合连接模式
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public bool IsRendezvous
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                this.SetSocketOption(SOCKOPT.UDT_RENDEZVOUS, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(1);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_RENDEZVOUS, ptr, 1);
                    return Convert.ToBoolean(Marshal.ReadByte(ptr));
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// 复用一个已存在的端口或者创建一个新的端口
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public bool IsReuseAddress
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                this.SetSocketOption(SOCKOPT.UDT_REUSEADDR, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(1);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_REUSEADDR, ptr, 1);
                    return Convert.ToBoolean(Marshal.ReadByte(ptr));
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// 设置关闭时是否等待数据发送完成
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public bool IsClosedLinger
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                this.SetSocketOption(SOCKOPT.UDT_LINGER, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(1);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_REUSEADDR, ptr, 1);
                    return Convert.ToBoolean(Marshal.ReadByte(ptr));
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// 是否同步接收
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public bool IsReviceSyn
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                this.SetSocketOption(SOCKOPT.UDT_RCVSYN, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(1);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_RCVSYN, ptr, 1);
                    return Convert.ToBoolean(Marshal.ReadByte(ptr));
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        /// <summary>
        /// 是否同步发送
        /// </summary>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public bool IsSendSyn
        {
            set
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                this.SetSocketOption(SOCKOPT.UDT_RCVSYN, value);
            }
            get
            {
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
                IntPtr ptr = Marshal.AllocHGlobal(1);
                try
                {
                    this.GetSocketOption(SOCKOPT.UDT_SNDSYN, ptr, 1);
                    return Convert.ToBoolean(Marshal.ReadByte(ptr));
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
        }

        private UDTSocket(IntPtr handle)
        {
            this.Handle = handle;
        }

        /// <summary>
        /// 绑定本机地址
        /// </summary>
        /// <param name="ip">本机IP</param>
        /// <param name="port">监听端口</param>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public void Bind(string ip, int port)
        {
            if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            if (NativeUDT.Bind(this.Handle, this.Family, this.SocketType, ip, port) != 0)
            {
                throw GetUDTException();
            }
        }

        private Socket bindSocket = null;

        /// <summary>
        /// 绑定现有Socket
        /// </summary>
        /// <param name="socket">现有Socket</param>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public void Bind(Socket socket)
        {
            if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            this.Bind(socket.Handle);
            bindSocket = socket;
        }

        /// <summary>
        /// 绑定现有Socket
        /// </summary>
        /// <param name="socket">现有Socket句柄</param>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public void Bind(IntPtr udpHandle)
        {
            if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            if (udpHandle == IntPtr.Zero)
            {
                throw new ArgumentException("udpHandle");
            }
            if (NativeUDT.BindSocket(this.Handle, udpHandle) != 0)
            {
                throw GetUDTException();
            }
        }

        /// <summary>
        /// 启动监听
        /// </summary>
        /// <param name="backlog">挂起连接队列的最大长度</param>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public void Listen(int backlog)
        {
            if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            if (NativeUDT.Listen(this.Handle, backlog) != 0)
            {
                throw GetUDTException();
            }
        }

        /// <summary>
        /// 建立与远程主机的连接
        /// </summary>
        /// <param name="ip">远程主机的名称</param>
        /// <param name="port">远程主机的端口号</param>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public void Connect(string ip, int port)
        {
            if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            if (NativeUDT.Connect(this.Handle, this.Family, this.SocketType, ip, port) != 0)
            {
                throw GetUDTException();
            }
        }

        public IAsyncResult BeginConnect(string ip, int port, AsyncCallback asyncCallback, object state = null)
        {
            ConnectHandle func = new ConnectHandle(this.Connect);
            AsyncCallback callbackDelegate = asyncCallback;
            if (asyncCallback != null)
            {
                AsyncCallbackDelegate tmp = new AsyncCallbackDelegate(asyncCallback) { Delegate = func };
                callbackDelegate = tmp.AsyncCallBack;
            }
            var asyncResult = func.BeginInvoke(ip, port, callbackDelegate, state);
            return new AsyncResultDelegate(asyncResult) { Delegate = func };
        }

        public void EndConnect(IAsyncResult ra)
        {
            AsyncResultDelegate asyncResultDelegate = (AsyncResultDelegate)ra;
            ConnectHandle fun = (ConnectHandle)asyncResultDelegate.Delegate;
            fun.EndInvoke(asyncResultDelegate.AsyncResult);
        }

        /// <summary>
        /// 为新建连接创建新的UDTSocket
        /// </summary>
        /// <param name="remote">请求连接的远程地址</param>
        /// <returns>连接的客户端</returns>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        unsafe public UDTSocket Accept(out IPEndPoint remote)
        {
            if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            int port = 0;
            byte[] ip = new byte[15];
            fixed (byte* ptr = ip)
            {
                int iplen = 0;
                IntPtr acceptHandle = NativeUDT.Accept(this.Handle, ptr, ref iplen, ref port);
                if (acceptHandle == IntPtr.Zero)
                {
                    throw GetUDTException();
                }
                else
                {
                    remote = new IPEndPoint(IPAddress.Parse(Encoding.Default.GetString(ip, 0, iplen)), port);

                    UDTSocket sock = new UDTSocket(acceptHandle);
                    sock.Family = this.Family;
                    sock.SocketType = this.SocketType;
                    return sock;
                }
            }
        }

        public IAsyncResult BeginAccept(AsyncCallback asyncCallback, object state = null)
        {
            IPEndPoint remote = null;
            AcceptHandle<UDTSocket> func = new AcceptHandle<UDTSocket>(this.Accept);
            AsyncCallback callbackDelegate = asyncCallback;
            if (asyncCallback != null)
            {
                AsyncCallbackDelegate tmp = new AsyncCallbackDelegate(asyncCallback) { Delegate = func };
                callbackDelegate = tmp.AsyncCallBack;
            }
            var asyncResult = func.BeginInvoke(out remote, callbackDelegate, state);
            return new AsyncResultDelegate(asyncResult) { Delegate = func };
        }

        public UDTSocket EndAccept(IAsyncResult ra, out IPEndPoint remote)
        {
            AsyncResultDelegate asyncResultDelegate = (AsyncResultDelegate)ra;
            AcceptHandle<UDTSocket> fun = (AcceptHandle<UDTSocket>)asyncResultDelegate.Delegate;
            return fun.EndInvoke(out remote, asyncResultDelegate.AsyncResult);
        }

        public IAsyncResult BeginClose(AsyncCallback asyncCallback, object state = null)
        {
            Action func = new Action(this.Close);
            AsyncCallback callbackDelegate = asyncCallback;
            if (asyncCallback != null)
            {
                AsyncCallbackDelegate tmp = new AsyncCallbackDelegate(asyncCallback) { Delegate = func };
                callbackDelegate = tmp.AsyncCallBack;
            }
            var asyncResult = func.BeginInvoke(callbackDelegate, state);
            return new AsyncResultDelegate(asyncResult) { Delegate = func };
        }

        public void EndClose(IAsyncResult ra)
        {
            AsyncResultDelegate asyncResultDelegate = (AsyncResultDelegate)ra;
            Action fun = (Action)asyncResultDelegate.Delegate;
            fun.EndInvoke(asyncResultDelegate.AsyncResult);
        }

        /// <summary>
        /// 关闭连接
        /// </summary>
        public void Close()
        {
            this.Dispose();
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="buffer">发送缓冲区</param>
        /// <param name="offset">发送起始索引</param>
        /// <param name="len">需要发送的数据长度</param>
        /// <returns>发送的数据大小</returns>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        /// <remarks>数据长度0不代表发送失败,只说明发送的数据量为0</remarks>

        [MethodImpl(MethodImplOptions.Synchronized)]
        unsafe public int Send(byte[] buffer, int offset, int len)
        {
#if UsingIntPtr
            IntPtr ptr = Marshal.AllocHGlobal(len);
            Marshal.Copy(buffer, offset, ptr, len);
            int sendLen = NativeUDT.Send(this.Handle, ptr, len);
            Marshal.FreeHGlobal(ptr);
            if (sendLen < 0) throw GetUDTException();
            return sendLen;
#else
            if (!this.IsSendSyn)
            {
                List<UDTSocket> writefds = new List<UDTSocket>();
                while (!this.IsDisposed && writefds.Count == 0)
                {
                    writefds.Add(this);
                    UDTSocket.Select(null, writefds, null, 1000);
                }
                if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            }
            fixed (byte* ptr = &buffer[offset])
            {
                int sendlen = NativeUDT.Send(this.Handle, ptr, len);
                if (sendlen < 0)
                {
                    throw GetUDTException();
                }
                return sendlen;
            }
#endif
        }

        /// <summary>
        /// 异步发送数据
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="len"></param>
        /// <param name="asyncCallback"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        /// <remarks>异步发送不保证数据发送的顺序</remarks>
        public IAsyncResult BeginSend(byte[] buffer, int offset, int len, AsyncCallback asyncCallback, object state = null)
        {
            TransferHandle func = new TransferHandle(this.Send);
            AsyncCallback callbackDelegate = asyncCallback;
            if (asyncCallback != null)
            {
                AsyncCallbackDelegate tmp = new AsyncCallbackDelegate(asyncCallback) { Delegate = func };
                callbackDelegate = tmp.AsyncCallBack;
            }
            byte[] data = new byte[len];
            Array.Copy(buffer, offset, data, 0, len);
            var asyncResult = func.BeginInvoke(data, 0, len, callbackDelegate, state);
            return new AsyncResultDelegate(asyncResult) { Delegate = func };
        }

        public int EndSend(IAsyncResult ra)
        {
            AsyncResultDelegate asyncResultDelegate = (AsyncResultDelegate)ra;
            TransferHandle fun = (TransferHandle)asyncResultDelegate.Delegate;
            int len = fun.EndInvoke(asyncResultDelegate.AsyncResult);
            return len;
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="buffer">接收缓冲区</param>
        /// <param name="offset">接收缓冲区起始索引</param>
        /// <param name="len">最大接收长度</param>
        /// <returns>接收的数据大小</returns>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        /// <remarks>接收数据长度0不代表客户端关闭,只说明接收的数据量为0</remarks>
        unsafe public int Receive(byte[] buffer, int offset, int len)
        {
#if UsingIntPtr
            IntPtr ptr = Marshal.AllocHGlobal(len);
            int reviceLen = NativeUDT.Receive(this.Handle, ptr, len);
            if (reviceLen > 0)
            {
                Marshal.Copy(ptr, buffer, offset, reviceLen);
            }
            Marshal.FreeHGlobal(ptr);
            if (reviceLen < 0) throw GetUDTException();
            return reviceLen;
#else
            if (!this.IsReviceSyn && !this.IsDisposed)
            {
                List<UDTSocket> readfds = new List<UDTSocket>();
                readfds.Add(this);
                UDTSocket.Select(readfds, null, null, 1000);
                if (readfds.Count == 0)
                {
                    return 0;
                }
            }
            if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            fixed (byte* ptr = &buffer[offset])
            {
                int reviceLen = NativeUDT.Receive(this.Handle, ptr, len);
                if (reviceLen < 0 && NativeUDT.GetErrorCode() != 0)
                {
                    GetUDTException();
                }
                return reviceLen;
            }
#endif
        }

        [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
        public IAsyncResult BeginReceive(byte[] buffer, int offset, int len, AsyncCallback asyncCallback, object state = null)
        {
            TransferHandle func = new TransferHandle(this.Receive);
            AsyncCallback callBack = asyncCallback;
            if (asyncCallback != null)
            {
                AsyncCallbackDelegate tmp = new AsyncCallbackDelegate(asyncCallback) { Delegate = func };
                callBack = tmp.AsyncCallBack;
            }
            var asyncResult = func.BeginInvoke(buffer, offset, len, callBack, state);
            return new AsyncResultDelegate(asyncResult) { Delegate = func };
        }

        public int EndReceive(IAsyncResult ra)
        {
            AsyncResultDelegate asyncResultDelegate = (AsyncResultDelegate)ra;
            TransferHandle fun = (TransferHandle)asyncResultDelegate.Delegate;
            int len = fun.EndInvoke(asyncResultDelegate.AsyncResult);
            return len;
        }

        /// <summary>
        /// 设置UDT相关属性
        /// </summary>
        /// <param name="optname"></param>
        /// <param name="value"></param>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public void SetSocketOption(SOCKOPT optname, int value)
        {
            if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            int result = NativeUDT.SetSocketOption(this.Handle, 0, optname, ref value, sizeof(int));
            if (result != 0)
            {
                throw GetUDTException();
            }
        }

        /// <summary>
        /// 设置UDT相关属性
        /// </summary>
        /// <param name="optname"></param>
        /// <param name="value"></param>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public void SetSocketOption(SOCKOPT optname, bool value)
        {
            if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            int result = NativeUDT.SetSocketOption(this.Handle, 0, optname, ref value, sizeof(bool));
            if (result != 0)
            {
                throw GetUDTException();
            }
        }

        /// <summary>
        /// 获取UDT相关属性
        /// </summary>
        /// <param name="optname"></param>
        /// <param name="ptr"></param>
        /// <param name="len"></param>
        /// <exception cref="UDTException"/>
        /// <exception cref="ObjectDisposedException">UDT被释放时引发</exception>
        public void GetSocketOption(SOCKOPT optname, IntPtr ptr, int len)
        {
            if (this.IsDisposed) throw new ObjectDisposedException("UDTSocket");
            int result = NativeUDT.GetSocketOption(this.Handle, 0, optname, ptr, ref len);
            if (result != 0)
            {
                throw GetUDTException();
            }
        }

        private static UDTException GetUDTException()
        {
            int len = 2048;
            StringBuilder sb = new StringBuilder(len);
            int errorCode = 0;
            int errorLen = 0;
            NativeUDT.GetErrorMessage(sb, len, ref errorLen, ref errorCode);
            return new UDTException(sb.ToString().Substring(0, errorLen), errorCode);
        }

        private static void MicrosecondsToTimeValue(long microSeconds, ref TimeValue socketTime)
        {
            socketTime.Seconds = (int)(microSeconds / 0xf4240L);
            socketTime.Microseconds = (int)(microSeconds % 0xf4240L);
        }

        public static int Select(IList<UDTSocket> checkRead, IList<UDTSocket> checkWrite, IList<UDTSocket> checkError, int microSeconds)
        {
            if ((((checkRead == null) || (checkRead.Count == 0)) && ((checkWrite == null) || (checkWrite.Count == 0))) && ((checkError == null) || (checkError.Count == 0)))
            {
                throw new ArgumentNullException("checkRead or checkWrite or checkError must be one is not null.");
            }
            IntPtr[] readfds = SocketListToFileDescriptorSet(checkRead);
            IntPtr[] writefds = SocketListToFileDescriptorSet(checkWrite);
            IntPtr[] exceptfds = SocketListToFileDescriptorSet(checkError);
            int readlen = readfds == null ? 0 : readfds.Length;
            int writelen = writefds == null ? 0 : writefds.Length;
            int exceptlen = exceptfds == null ? 0 : exceptfds.Length;
            int result = 0;
            if (microSeconds != -1)
            {
                TimeValue socketTime = new TimeValue();
                MicrosecondsToTimeValue((long)((ulong)microSeconds), ref socketTime);
                result = NativeUDT.Select(0, readfds, ref readlen, writefds, ref writelen, exceptfds, ref exceptlen, ref socketTime);
            }
            else
            {
                result = NativeUDT.Select(0, readfds, ref readlen, writefds, ref writelen, exceptfds, ref exceptlen, IntPtr.Zero);
            }

            SelectFileDescriptor(checkRead, readfds, readlen);
            SelectFileDescriptor(checkWrite, writefds, writelen);
            SelectFileDescriptor(checkError, exceptfds, exceptlen);
            return result;
        }

        private static void SelectFileDescriptor(IList<UDTSocket> socketList, IntPtr[] fileDescriptorSet, int len)
        {
            if ((socketList != null) && (socketList.Count != 0))
            {
                if (len == 0)
                {
                    socketList.Clear();
                }
                else
                {
                    lock (socketList)
                    {
                        for (int i = 0; i < socketList.Count; i++)
                        {
                            UDTSocket socket = socketList[i];
                            int num2 = 0;
                            while (num2 < len)
                            {
                                if (fileDescriptorSet[num2] == socket.Handle)
                                {
                                    break;
                                }
                                num2++;
                            }
                            if (num2 == ((int)fileDescriptorSet[0]))
                            {
                                socketList.RemoveAt(i--);
                            }
                        }
                    }
                }
            }
        }

        private static IntPtr[] SocketListToFileDescriptorSet(IList<UDTSocket> socketList)
        {
            if ((socketList == null) || (socketList.Count == 0))
            {
                return null;
            }
            IntPtr[] ptrArray = new IntPtr[socketList.Count];
            for (int i = 0; i < socketList.Count; i++)
            {
                ptrArray[i] = socketList[i].Handle;
            }
            return ptrArray;
        }

        public override bool IsExpaired()
        {
            return false;
        }

        protected override void SingleDispose()
        {
            NativeUDT.Close(this.Handle);
            if (this.bindSocket != null)
            {
                this.bindSocket.Dispose();
            }
        }
    }


Collect.cs

    public abstract class Collect : ICollect
    { 

        ~Collect()
        {
            this.Dispose();
        }

        public abstract bool IsExpaired();

        private long dispoing = 0;

        public bool IsDisposed
        {
            get
            {
                return Interlocked.Read(ref dispoing) == 0 ? false : true;
            }
        }

        protected abstract void SingleDispose();

        public void Dispose()
        {
            if (Interlocked.Exchange(ref dispoing, 1) == 0)
            { 
                this.SingleDispose(); 
            }
            GC.SuppressFinalize(this);
        }
    }

调用方法

  private UDTSocket CreateSocket(string ip = "0.0.0.0", int port = 0, bool rendezvous = false)
        {
            UDTSocket sock = new UDTSocket(AddressFamily.InterNetwork, SocketType.Stream);
            int bufferSize = 64000;
            sock.UDTSendBufferSize = sock.UDTReviceBufferSize = sock.UDPReviceBufferSize = sock.UDPSendBufferSize = bufferSize;
            sock.WindowSize = 16;
            sock.IsRendezvous = rendezvous;
            sock.IsClosedLinger = false;
            sock.IsReuseAddress = true;
            sock.MSS = (int)this.numMTU.Value;
            sock.Bind("0.0.0.0", port);
            return sock;
        }


 


呵呵  第一次写博客

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值