public void Listen(IPEndPoint localEP, int backlog)
        {
            in_addr inAddress = new in_addr();

            inAddress.s_b1 = localEP.Address.GetAddressBytes()[0];
            inAddress.s_b2 = localEP.Address.GetAddressBytes()[1];
            inAddress.s_b3 = localEP.Address.GetAddressBytes()[2];
            inAddress.s_b4 = localEP.Address.GetAddressBytes()[3];

            sockaddr_in sa = new sockaddr_in();

            sa.sin_family = ADDRESS_FAMILIES.AF_INET;
            sa.sin_port   = WinSock.htons((ushort)localEP.Port);
            //Imports.ThrowLastWSAError();
            sa.sin_addr = inAddress;

            unsafe
            {
                if (WinSock.bind(_listenerSocket, ref sa, sizeof(sockaddr_in)) == WinSock.SOCKET_ERROR)
                {
                    WinSock.ThrowLastWSAError();
                }
            }

            if (WinSock.listen(_listenerSocket, backlog) == WinSock.SOCKET_ERROR)
            {
                WinSock.ThrowLastWSAError();
            }

            foreach (var s in allSockets)
            {
                BeginAccept(s);
            }
        }
Exemple #2
0
        unsafe void ProcessSendCompletes(object o)
        {
            const int         maxResults = 1024;
            RIO_RESULT *      results    = stackalloc RIO_RESULT[maxResults];
            uint              count;
            IntPtr            key, bytes;
            NativeOverlapped *overlapped = stackalloc NativeOverlapped[1];

            while (true)
            {
                RioStatic.Notify(SendCompletionQueue);
                if (Kernel32.GetQueuedCompletionStatus(SendCompletionPort, out bytes, out key, out overlapped, -1) != 0)
                {
                    do
                    {
                        count = RioStatic.DequeueCompletion(SendCompletionQueue, (IntPtr)results, maxResults);
                        WinSock.ThrowLastWSAError();
                        for (var i = 0; i < count; i++)
                        {
                            var buf = SendBufferPool.AllSegments[results[i].RequestCorrelation];
                            if (buf.AutoFree)
                            {
                                buf.Dispose();
                            }
                        }
                    } while (count > 0);
                }
                else
                {
                    Kernel32.ThrowLastError();
                }
            }
        }
        unsafe void ListenIocpComplete(object o)
        {
            IntPtr lpNumberOfBytes;
            IntPtr lpCompletionKey;
            RioNativeOverlapped *lpOverlapped = stackalloc RioNativeOverlapped[1];
            int lpcbTransfer;
            int lpdwFlags;

            while (true)
            {
                if (Kernel32.GetQueuedCompletionStatusRio(_listenIocp, out lpNumberOfBytes, out lpCompletionKey, out lpOverlapped, -1))
                {
                    if (WinSock.WSAGetOverlappedResult(_listenerSocket, lpOverlapped, out lpcbTransfer, false, out lpdwFlags))
                    {
                        var res = allSockets[lpOverlapped->SocketIndex];
                        activeSockets.TryAdd(res.GetHashCode(), res);
                        OnAccepted(res);
                    }
                    else
                    {
                        //recycle socket
                    }
                }
                else
                {
                    var error = Marshal.GetLastWin32Error();

                    if (error != 0 && error != 64) //connection no longer available
                    {
                        throw new Win32Exception(error);
                    }
                }
            }
        }
        public RioTcpClientPool(RioFixedBufferPool sendPool, RioFixedBufferPool revicePool, uint socketCount,
                                uint maxOutstandingReceive = 1024, uint maxOutstandingSend = 1024)
            : base(sendPool, revicePool, socketCount, maxOutstandingReceive, maxOutstandingSend, (maxOutstandingReceive + maxOutstandingSend) * socketCount)
        {
            foreach (var s in allSockets)
            {
                _freeSockets.Enqueue(s);

                in_addr inAddress = new in_addr();
                inAddress.s_b1 = 0;
                inAddress.s_b2 = 0;
                inAddress.s_b3 = 0;
                inAddress.s_b4 = 0;

                sockaddr_in sa = new sockaddr_in();
                sa.sin_family = ADDRESS_FAMILIES.AF_INET;
                sa.sin_port   = 0;
                //Imports.ThrowLastWSAError();
                sa.sin_addr = inAddress;

                unsafe
                {
                    if (WinSock.bind(s.Socket, ref sa, sizeof(sockaddr_in)) == WinSock.SOCKET_ERROR)
                    {
                        WinSock.ThrowLastWSAError();
                    }
                }
            }
        }
Exemple #5
0
 internal unsafe void CommitSend()
 {
     if (!RioStatic.Send(_requestQueue, RIO_BUFSEGMENT.NullSegment, 0, RIO_SEND_FLAGS.COMMIT_ONLY, 0))
     {
         WinSock.ThrowLastWSAError();
     }
 }
Exemple #6
0
 internal unsafe void SendInternal(RioBufferSegment segment, RIO_SEND_FLAGS flags)
 {
     if (!RioStatic.Send(_requestQueue, segment.SegmentPointer, 1, flags, segment.Index))
     {
         WinSock.ThrowLastWSAError();
     }
 }
Exemple #7
0
        internal unsafe static RIO Initalize(IntPtr socket)
        {
            uint dwBytes = 0;
            RIO_EXTENSION_FUNCTION_TABLE rio = new RIO_EXTENSION_FUNCTION_TABLE();
            Guid RioFunctionsTableId         = new Guid("8509e081-96dd-4005-b165-9e2ee8c79e3f");

            int True   = -1;
            var result = setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&True, 4);

            if (result != 0)
            {
                var error = WinSock.WSAGetLastError();
                WinSock.WSACleanup();
                throw new Exception(String.Format("ERROR: setsockopt TCP_NODELAY returned {0}", error));
            }

            result = WSAIoctlGeneral(socket, SIO_LOOPBACK_FAST_PATH,
                                     &True, 4, null, 0,
                                     out dwBytes, IntPtr.Zero, IntPtr.Zero);

            if (result != 0)
            {
                var error = WinSock.WSAGetLastError();
                WinSock.WSACleanup();
                throw new Exception(String.Format("ERROR: WSAIoctl SIO_LOOPBACK_FAST_PATH returned {0}", error));
            }

            result = WSAIoctl(socket, SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER,
                              ref RioFunctionsTableId, 16, ref rio,
                              sizeof(RIO_EXTENSION_FUNCTION_TABLE),
                              out dwBytes, IntPtr.Zero, IntPtr.Zero);

            if (result != 0)
            {
                var error = WinSock.WSAGetLastError();
                WinSock.WSACleanup();
                throw new Exception(String.Format("ERROR: RIOInitalize returned {0}", error));
            }
            else
            {
                RIO rioFunctions = new RIO
                {
                    RegisterBuffer        = Marshal.GetDelegateForFunctionPointer <RIORegisterBuffer>(rio.RIORegisterBuffer),
                    CreateCompletionQueue = Marshal.GetDelegateForFunctionPointer <RIOCreateCompletionQueue>(rio.RIOCreateCompletionQueue),
                    CreateRequestQueue    = Marshal.GetDelegateForFunctionPointer <RIOCreateRequestQueue>(rio.RIOCreateRequestQueue),
                    Notify            = Marshal.GetDelegateForFunctionPointer <RIONotify>(rio.RIONotify),
                    DequeueCompletion = Marshal.GetDelegateForFunctionPointer <RIODequeueCompletion>(rio.RIODequeueCompletion),
                    Receive           = Marshal.GetDelegateForFunctionPointer <RIOReceive>(rio.RIOReceive),
                    Send = Marshal.GetDelegateForFunctionPointer <RIOSend>(rio.RIOSend),
                    CloseCompletionQueue  = Marshal.GetDelegateForFunctionPointer <RIOCloseCompletionQueue>(rio.RIOCloseCompletionQueue),
                    DeregisterBuffer      = Marshal.GetDelegateForFunctionPointer <RIODeregisterBuffer>(rio.RIODeregisterBuffer),
                    ResizeCompletionQueue = Marshal.GetDelegateForFunctionPointer <RIOResizeCompletionQueue>(rio.RIOResizeCompletionQueue),
                    ResizeRequestQueue    = Marshal.GetDelegateForFunctionPointer <RIOResizeRequestQueue>(rio.RIOResizeRequestQueue)
                };
                return(rioFunctions);
            }
        }
Exemple #8
0
 public void WritePreAllocated(RioBufferSegment Segment)
 {
     unsafe
     {
         if (!RioStatic.Send(_requestQueue, Segment.SegmentPointer, 1, RIO_SEND_FLAGS.DEFER, Segment.Index))
         {
             WinSock.ThrowLastWSAError();
         }
     }
 }
        protected override unsafe void SocketIocpComplete(object o)
        {
            IntPtr lpNumberOfBytes;
            IntPtr lpCompletionKey;
            RioNativeOverlapped *lpOverlapped = stackalloc RioNativeOverlapped[1];
            TaskCompletionSource <RioConnectionOrientedSocket> r;
            RioConnectionOrientedSocket res;
            int lpcbTransfer;
            int lpdwFlags;

            while (true)
            {
                if (Kernel32.GetQueuedCompletionStatusRio(socketIocp, out lpNumberOfBytes, out lpCompletionKey, out lpOverlapped, -1))
                {
                    if (lpOverlapped->Status == 1)
                    {
                        _freeSockets.Enqueue(allSockets[lpOverlapped->SocketIndex]);
                    }
                    else if (lpOverlapped->Status == 2)
                    {
                        if (WinSock.WSAGetOverlappedResult(allSockets[lpOverlapped->SocketIndex].Socket, lpOverlapped, out lpcbTransfer, false, out lpdwFlags))
                        {
                            res = allSockets[lpOverlapped->SocketIndex];
                            activeSockets.TryAdd(res.GetHashCode(), res);
                            if (_ongoingConnections.TryRemove(res, out r))
                            {
                                r.SetResult(res);
                            }
                        }
                        else
                        {
                            //recycle socket
                        }
                    }
                } //1225
                else
                {
                    var error = Marshal.GetLastWin32Error();

                    if (error != 0 && error != 64 & error != 1225) //connection no longer available
                    {
                        throw new Win32Exception(error);
                    }
                    else
                    {
                        res = allSockets[lpOverlapped->SocketIndex];
                        _freeSockets.Enqueue(allSockets[lpOverlapped->SocketIndex]);
                        if (_ongoingConnections.TryRemove(res, out r))
                        {
                            r.SetException(new Win32Exception(error));
                        }
                    }
                }
            }
        }
Exemple #10
0
        internal static int ThrowLastWSAError()
        {
            var error = WinSock.WSAGetLastError();

            if (error != 0)
            {
                throw new Win32Exception(error);
            }
            else
            {
                return(error);
            }
        }
Exemple #11
0
        internal RioSocketBase(RioFixedBufferPool sendBufferPool, RioFixedBufferPool receiveBufferPool,
                               uint maxOutstandingReceive, uint maxOutstandingSend, IntPtr SendCompletionQueue, IntPtr ReceiveCompletionQueue,
                               ADDRESS_FAMILIES adressFam, SOCKET_TYPE sockType, PROTOCOL protocol)
        {
            if ((Socket = WinSock.WSASocket(adressFam, sockType, protocol, IntPtr.Zero, 0, SOCKET_FLAGS.REGISTERED_IO | SOCKET_FLAGS.WSA_FLAG_OVERLAPPED)) == IntPtr.Zero)
            {
                WinSock.ThrowLastWSAError();
            }

            SendBufferPool    = sendBufferPool;
            ReceiveBufferPool = receiveBufferPool;

            _requestQueue = RioStatic.CreateRequestQueue(Socket, maxOutstandingReceive, 1, maxOutstandingSend, 1, ReceiveCompletionQueue, SendCompletionQueue, GetHashCode());
            WinSock.ThrowLastWSAError();
        }
Exemple #12
0
        public virtual void Dispose()
        {
            RioStatic.DeregisterBuffer(_sendBufferId);
            RioStatic.DeregisterBuffer(_reciveBufferId);

            Kernel32.CloseHandle(SendCompletionPort);
            Kernel32.CloseHandle(ReceiveCompletionPort);
            RioStatic.CloseCompletionQueue(SendCompletionQueue);
            RioStatic.CloseCompletionQueue(ReceiveCompletionQueue);

            WinSock.WSACleanup();

            SendBufferPool.Dispose();
            ReceiveBufferPool.Dispose();
        }
        internal unsafe virtual void Recycle(RioConnectionOrientedSocket socket)
        {
            RioSocketBase c;

            activeSockets.TryRemove(socket.GetHashCode(), out c);
            socket.ResetOverlapped();
            socket._overlapped->Status = 1;
            if (!RioStatic.DisconnectEx(c.Socket, socket._overlapped, 0x02, 0)) //TF_REUSE_SOCKET
            {
                if (WinSock.WSAGetLastError() != 997)                           // error_io_pending
                {
                    WinSock.ThrowLastWSAError();
                }
            }
            //else
            //    AcceptEx(socket);
        }
        unsafe void BeginAccept(RioConnectionOrientedSocket acceptSocket)
        {
            int recived = 0;

            acceptSocket.ResetOverlapped();
            if (!RioStatic.AcceptEx(_listenerSocket, acceptSocket.Socket, acceptSocket._adressBuffer, 0, sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, out recived, acceptSocket._overlapped))
            {
                if (WinSock.WSAGetLastError() != 997) // error_io_pending
                {
                    WinSock.ThrowLastWSAError();
                }
            }
            else
            {
                OnAccepted(acceptSocket);
            }
        }
Exemple #15
0
        unsafe void ProcessReceiveCompletes(object o)
        {
            const int         maxResults = 1024;
            RIO_RESULT *      results    = stackalloc RIO_RESULT[maxResults];
            RioSocketBase     connection;
            uint              count;
            IntPtr            key, bytes;
            NativeOverlapped *overlapped = stackalloc NativeOverlapped[1];
            RIO_RESULT        result;
            RioBufferSegment  buf;

            while (true)
            {
                RioStatic.Notify(ReceiveCompletionQueue);
                WinSock.ThrowLastWSAError();

                if (Kernel32.GetQueuedCompletionStatus(ReceiveCompletionPort, out bytes, out key, out overlapped, -1) != 0)
                {
                    do
                    {
                        count = RioStatic.DequeueCompletion(ReceiveCompletionQueue, (IntPtr)results, maxResults);
                        WinSock.ThrowLastWSAError();

                        for (var i = 0; i < count; i++)
                        {
                            result = results[i];
                            buf    = ReceiveBufferPool.AllSegments[result.RequestCorrelation];
                            if (activeSockets.TryGetValue(result.ConnectionCorrelation, out connection))
                            {
                                buf.SegmentPointer->Length = (int)result.BytesTransferred;
                                connection.onIncommingSegment(buf);
                            }
                            else
                            {
                                buf.Dispose();
                            }
                        }
                    } while (count > 0);
                }
                else
                {
                    Kernel32.ThrowLastError();
                }
            }
        }
        public unsafe Task <RioConnectionOrientedSocket> Connect(Uri adress)
        {
            var adr = Dns.GetHostAddressesAsync(adress.Host).Result.First(i => i.AddressFamily == AddressFamily.InterNetwork);

            in_addr inAddress = new in_addr();

            inAddress.s_b1 = adr.GetAddressBytes()[0];
            inAddress.s_b2 = adr.GetAddressBytes()[1];
            inAddress.s_b3 = adr.GetAddressBytes()[2];
            inAddress.s_b4 = adr.GetAddressBytes()[3];

            sockaddr_in sa = new sockaddr_in();

            sa.sin_family = ADDRESS_FAMILIES.AF_INET;
            sa.sin_port   = WinSock.htons((ushort)adress.Port);
            //Imports.ThrowLastWSAError();
            sa.sin_addr = inAddress;

            RioConnectionOrientedSocket s;

            _freeSockets.TryDequeue(out s);
            var tcs = new TaskCompletionSource <RioConnectionOrientedSocket>();

            _ongoingConnections.TryAdd(s, tcs);

            uint gurka;

            unsafe
            {
                s.ResetOverlapped();
                s._overlapped->Status = 2;
                if (!RioStatic.ConnectEx(s.Socket, sa, sizeof(sockaddr_in), IntPtr.Zero, 0, out gurka, s._overlapped))
                {
                    if (WinSock.WSAGetLastError() != 997) // error_io_pending
                    {
                        WinSock.ThrowLastWSAError();
                    }
                }
            }

            return(tcs.Task);
        }
Exemple #17
0
        internal unsafe void ReciveInternal()
        {
            RioBufferSegment buf;

            if (ReceiveBufferPool.TryGetBuffer(out buf))
            {
                if (!RioStatic.Receive(_requestQueue, buf.SegmentPointer, 1, RIO_RECEIVE_FLAGS.NONE, buf.Index))
                {
                    WinSock.ThrowLastWSAError();
                }
            }
            else
            {
                ThreadPool.QueueUserWorkItem(o =>
                {
                    var b = ReceiveBufferPool.GetBuffer();
                    if (!RioStatic.Receive(_requestQueue, ReceiveBufferPool.GetBuffer().SegmentPointer, 1, RIO_RECEIVE_FLAGS.NONE, b.Index))
                    {
                        WinSock.ThrowLastWSAError();
                    }
                }, null);
            }
        }
        public unsafe RioTcpListener(RioFixedBufferPool sendPool, RioFixedBufferPool revicePool, uint socketCount, uint maxOutstandingReceive = 1024, uint maxOutstandingSend = 1024)
            : base(sendPool, revicePool, socketCount, maxOutstandingReceive, maxOutstandingSend, (maxOutstandingReceive + maxOutstandingSend) * socketCount)
        {
            if ((_listenerSocket = WinSock.WSASocket(ADDRESS_FAMILIES.AF_INET, SOCKET_TYPE.SOCK_STREAM, PROTOCOL.IPPROTO_TCP, IntPtr.Zero, 0, SOCKET_FLAGS.REGISTERED_IO | SOCKET_FLAGS.WSA_FLAG_OVERLAPPED)) == IntPtr.Zero)
            {
                WinSock.ThrowLastWSAError();
            }

            int    True    = -1;
            UInt32 dwBytes = 0;

            WinSock.setsockopt(_listenerSocket, WinSock.IPPROTO_TCP, WinSock.TCP_NODELAY, (char *)&True, 4);
            WinSock.WSAIoctlGeneral(_listenerSocket, WinSock.SIO_LOOPBACK_FAST_PATH, &True, 4, null, 0, out dwBytes, IntPtr.Zero, IntPtr.Zero);

            if ((_listenIocp = Kernel32.CreateIoCompletionPort(_listenerSocket, _listenIocp, 0, 1)) == IntPtr.Zero)
            {
                Kernel32.ThrowLastError();
            }

            Thread ListenIocpThread = new Thread(ListenIocpComplete);

            ListenIocpThread.IsBackground = true;
            ListenIocpThread.Start();
        }
Exemple #19
0
        internal unsafe static void Initalize()
        {
            IntPtr tempSocket;

            tempSocket = WinSock.WSASocket(ADDRESS_FAMILIES.AF_INET, SOCKET_TYPE.SOCK_STREAM, PROTOCOL.IPPROTO_TCP, IntPtr.Zero, 0, SOCKET_FLAGS.REGISTERED_IO | SOCKET_FLAGS.WSA_FLAG_OVERLAPPED);
            WinSock.ThrowLastWSAError();

            uint dwBytes = 0;

            Guid AcceptExId  = new Guid("B5367DF1-CBAC-11CF-95CA-00805F48A192");
            var  acceptExptr = IntPtr.Zero;

            if (WinSock.WSAIoctl2(tempSocket,
                                  WinSock.SIO_GET_EXTENSION_FUNCTION_POINTER,
                                  ref AcceptExId,
                                  16,
                                  ref acceptExptr,
                                  IntPtr.Size,
                                  out dwBytes,
                                  IntPtr.Zero,
                                  IntPtr.Zero) != 0)
            {
                WinSock.ThrowLastWSAError();
            }
            else
            {
                AcceptEx = Marshal.GetDelegateForFunctionPointer <WinSock.AcceptEx>(acceptExptr);
            }


            Guid ConnectExId  = new Guid("25A207B9-DDF3-4660-8EE9-76E58C74063E");
            var  ConnectExptr = IntPtr.Zero;

            if (WinSock.WSAIoctl2(tempSocket,
                                  WinSock.SIO_GET_EXTENSION_FUNCTION_POINTER,
                                  ref ConnectExId,
                                  16,
                                  ref ConnectExptr,
                                  IntPtr.Size,
                                  out dwBytes,
                                  IntPtr.Zero,
                                  IntPtr.Zero) != 0)
            {
                WinSock.ThrowLastWSAError();
            }
            else
            {
                ConnectEx = Marshal.GetDelegateForFunctionPointer <WinSock.ConnectEx>(ConnectExptr);
            }


            Guid DisconnectExId  = new Guid("7FDA2E11-8630-436F-A031-F536A6EEC157");
            var  DisconnectExptr = IntPtr.Zero;

            if (WinSock.WSAIoctl2(tempSocket,
                                  WinSock.SIO_GET_EXTENSION_FUNCTION_POINTER,
                                  ref DisconnectExId,
                                  16,
                                  ref DisconnectExptr,
                                  IntPtr.Size,
                                  out dwBytes,
                                  IntPtr.Zero,
                                  IntPtr.Zero) != 0)
            {
                WinSock.ThrowLastWSAError();
            }
            else
            {
                DisconnectEx = Marshal.GetDelegateForFunctionPointer <WinSock.DisconnectEx>(DisconnectExptr);
            }

            var  rio = new RIO_EXTENSION_FUNCTION_TABLE();
            Guid RioFunctionsTableId = new Guid("8509e081-96dd-4005-b165-9e2ee8c79e3f");

            if (WinSock.WSAIoctl(tempSocket, WinSock.SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER,
                                 ref RioFunctionsTableId, 16, ref rio,
                                 sizeof(RIO_EXTENSION_FUNCTION_TABLE),
                                 out dwBytes, IntPtr.Zero, IntPtr.Zero) != 0)
            {
                WinSock.ThrowLastWSAError();
            }
            else
            {
                RegisterBuffer        = Marshal.GetDelegateForFunctionPointer <WinSock.RIORegisterBuffer>(rio.RIORegisterBuffer);
                CreateCompletionQueue = Marshal.GetDelegateForFunctionPointer <WinSock.RIOCreateCompletionQueue>(rio.RIOCreateCompletionQueue);
                CreateRequestQueue    = Marshal.GetDelegateForFunctionPointer <WinSock.RIOCreateRequestQueue>(rio.RIOCreateRequestQueue);
                Notify            = Marshal.GetDelegateForFunctionPointer <WinSock.RIONotify>(rio.RIONotify);
                DequeueCompletion = Marshal.GetDelegateForFunctionPointer <WinSock.RIODequeueCompletion>(rio.RIODequeueCompletion);
                Receive           = Marshal.GetDelegateForFunctionPointer <WinSock.RIOReceive>(rio.RIOReceive);
                Send = Marshal.GetDelegateForFunctionPointer <WinSock.RIOSend>(rio.RIOSend);
                CloseCompletionQueue  = Marshal.GetDelegateForFunctionPointer <WinSock.RIOCloseCompletionQueue>(rio.RIOCloseCompletionQueue);
                DeregisterBuffer      = Marshal.GetDelegateForFunctionPointer <WinSock.RIODeregisterBuffer>(rio.RIODeregisterBuffer);
                ResizeCompletionQueue = Marshal.GetDelegateForFunctionPointer <WinSock.RIOResizeCompletionQueue>(rio.RIOResizeCompletionQueue);
                ResizeRequestQueue    = Marshal.GetDelegateForFunctionPointer <WinSock.RIOResizeRequestQueue>(rio.RIOResizeRequestQueue);
            }

            WinSock.closesocket(tempSocket);
            WinSock.ThrowLastWSAError();
        }
 public override void Dispose()
 {
     Kernel32.CloseHandle(_listenIocp);
     WinSock.closesocket(_listenerSocket);
     base.Dispose();
 }
Exemple #21
0
        public unsafe RioSocketPool(RioFixedBufferPool sendPool, RioFixedBufferPool receivePool,
                                    uint maxOutstandingReceive = 1024, uint maxOutstandingSend = 1024, uint maxOutsandingCompletions = 2048)
        {
            MaxOutstandingReceive    = maxOutstandingReceive;
            MaxOutstandingSend       = maxOutstandingSend;
            MaxOutsandingCompletions = maxOutsandingCompletions;
            SendBufferPool           = sendPool;
            ReceiveBufferPool        = receivePool;

            var     version = new Version(2, 2);
            WSAData data;
            var     result = WinSock.WSAStartup((short)version.Raw, out data);

            if (result != 0)
            {
                WinSock.ThrowLastWSAError();
            }

            RioStatic.Initalize();

            if ((ReceiveCompletionPort = Kernel32.CreateIoCompletionPort((IntPtr)(-1), IntPtr.Zero, 0, 1)) == IntPtr.Zero)
            {
                Kernel32.ThrowLastError();
            }

            if ((SendCompletionPort = Kernel32.CreateIoCompletionPort((IntPtr)(-1), IntPtr.Zero, 0, 1)) == IntPtr.Zero)
            {
                Kernel32.ThrowLastError();
            }


            _sendBufferId = RioStatic.RegisterBuffer(SendBufferPool.BufferPointer, (uint)SendBufferPool.TotalLength);
            WinSock.ThrowLastWSAError();
            SendBufferPool.SetBufferId(_sendBufferId);

            _reciveBufferId = RioStatic.RegisterBuffer(ReceiveBufferPool.BufferPointer, (uint)ReceiveBufferPool.TotalLength);
            WinSock.ThrowLastWSAError();
            ReceiveBufferPool.SetBufferId(_reciveBufferId);

            var sendCompletionMethod = new RIO_NOTIFICATION_COMPLETION()
            {
                Type = RIO_NOTIFICATION_COMPLETION_TYPE.IOCP_COMPLETION,
                Iocp = new RIO_NOTIFICATION_COMPLETION_IOCP()
                {
                    IocpHandle       = SendCompletionPort,
                    QueueCorrelation = 0,
                    Overlapped       = (NativeOverlapped *)-1
                }
            };

            if ((SendCompletionQueue = RioStatic.CreateCompletionQueue(MaxOutsandingCompletions, sendCompletionMethod)) == IntPtr.Zero)
            {
                WinSock.ThrowLastWSAError();
            }

            var receiveCompletionMethod = new RIO_NOTIFICATION_COMPLETION()
            {
                Type = RIO_NOTIFICATION_COMPLETION_TYPE.IOCP_COMPLETION,
                Iocp = new RIO_NOTIFICATION_COMPLETION_IOCP()
                {
                    IocpHandle       = ReceiveCompletionPort,
                    QueueCorrelation = 0,
                    Overlapped       = (NativeOverlapped *)-1
                }
            };

            if ((ReceiveCompletionQueue = RioStatic.CreateCompletionQueue(MaxOutsandingCompletions, receiveCompletionMethod)) == IntPtr.Zero)
            {
                WinSock.ThrowLastWSAError();
            }


            Thread receiveThread = new Thread(ProcessReceiveCompletes);

            receiveThread.IsBackground = true;
            receiveThread.Start();
            Thread sendThread = new Thread(ProcessSendCompletes);

            sendThread.IsBackground = true;
            sendThread.Start();
        }
Exemple #22
0
 public virtual void Dispose()
 {
     WinSock.closesocket(Socket);
 }