示例#1
0
        protected override unsafe bool SocketIocpOk(RioConnectionOrientedSocket socket, byte status)
        {

            if (status == 1)
            {
                ThreadPool.QueueUserWorkItem(oo =>
                {
                    EndRecycle((RioConnectionOrientedSocket)oo, true);
                }, socket);
            }
            else if (status == 2)
            {
                TaskCompletionSource<RioSocket> r;
                activeSockets.TryAdd(socket.GetHashCode(), socket);
                socket.SetInUse(true);
                if (socket.SetSocketOption(SOL_SOCKET_SocketOptions.SO_UPDATE_CONNECT_CONTEXT, (void*)0, 0) != 0)
                    WinSock.ThrowLastWSAError();

                if (_ongoingConnections.TryRemove(socket, out r))
                    ThreadPool.QueueUserWorkItem(oo =>
                    {
                        var rr = (Tuple<TaskCompletionSource<RioSocket>, RioConnectionOrientedSocket>)oo;
                        rr.Item1.SetResult(rr.Item2);
                    }, Tuple.Create(r, socket));
            }

            return false;
        }
        public unsafe RioConnectionOrientedSocketPool(RioFixedBufferPool sendPool, RioFixedBufferPool revicePool, uint socketCount, ADDRESS_FAMILIES adressFam, SOCKET_TYPE sockType, PROTOCOL protocol,
            uint maxOutstandingReceive = 1024, uint maxOutstandingSend = 1024, uint maxConnections = 1024)
            : base(sendPool, revicePool, adressFam, sockType, protocol, maxOutstandingReceive, maxOutstandingSend, maxConnections)
        {
            var adrSize = (sizeof(sockaddr_in) + 16) * 2;
            var overlapped = Marshal.AllocHGlobal(new IntPtr(socketCount * Marshal.SizeOf<RioNativeOverlapped>()));
            var adressBuffer = Marshal.AllocHGlobal(new IntPtr(socketCount * adrSize));

            allSockets = new RioConnectionOrientedSocket[socketCount];

            for (int i = 0; i < socketCount; i++)
            {
                allSockets[i] = new RioConnectionOrientedSocket(overlapped + (i * Marshal.SizeOf<RioNativeOverlapped>()), adressBuffer + (i * adrSize), this, SendBufferPool, ReceiveBufferPool, maxOutstandingReceive, maxOutstandingSend, SendCompletionQueue, ReceiveCompletionQueue, adressFam, sockType, protocol);
                allSockets[i]._overlapped->SocketIndex = i;
            }

            if ((socketIocp = Kernel32.CreateIoCompletionPort((IntPtr)(-1), IntPtr.Zero, 0, 1)) == IntPtr.Zero)
                Kernel32.ThrowLastError();

            foreach (var s in allSockets)
            {
                if ((Kernel32.CreateIoCompletionPort(s.Socket, socketIocp, 0, 1)) == IntPtr.Zero)
                    Kernel32.ThrowLastError();
            }

            Thread SocketIocpThread = new Thread(SocketIocpComplete);
            SocketIocpThread.IsBackground = true;
            SocketIocpThread.Start();
        }
示例#3
0
 public RioStream(RioConnectionOrientedSocket socket)
 {
     _socket = socket;
     _currentInputSegment = null;
     _currentOutputSegment = _socket.SendBufferPool.GetBuffer();
     _getNewSegmentDelegate = GetNewSegment;
     socket.OnIncommingSegment = s => _incommingSegments.Set(s);
     socket.ReciveInternal();
 }
 internal unsafe virtual void Recycle(RioConnectionOrientedSocket socket)
 {
     RioSocket c;
     activeSockets.TryRemove(socket.GetHashCode(), out c);
     socket.ResetOverlapped();
     socket._overlapped->Status = 1;
     if (!RioStatic.DisconnectEx(socket.Socket, socket._overlapped, disconnectexflag, 0)) //TF_REUSE_SOCKET
         if (WinSock.WSAGetLastError() != 997) // error_io_pending
             WinSock.ThrowLastWSAError();
     //else
     //    AcceptEx(socket);
 }
示例#5
0
 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);
 }
示例#6
0
        internal override void InitializeSocket(RioConnectionOrientedSocket socket)
        {
            socket.SetLoopbackFastPath(true);
            socket.SetTcpNoDelay(true);
            sockaddr_in sa = new sockaddr_in();
            sa.sin_family = adressFam;

            unsafe
            {
                if (WinSock.bind(socket.Socket, ref sa, sizeof(sockaddr_in)) == WinSock.SOCKET_ERROR)
                    WinSock.ThrowLastWSAError();
            }
        }
        internal unsafe virtual void Recycle(RioConnectionOrientedSocket socket)
        {
            RioSocket c;

            activeSockets.TryRemove(socket.GetHashCode(), out c);
            socket.ResetOverlapped();
            socket._overlapped->Status = 1;
            if (!RioStatic.DisconnectEx(socket.Socket, socket._overlapped, 0x02, 0)) //TF_REUSE_SOCKET
            {
                if (WinSock.WSAGetLastError() != 997)                                // error_io_pending
                {
                    WinSock.ThrowLastWSAError();
                }
            }
            //else
            //    AcceptEx(socket);
        }
示例#8
0
        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);
            }
        }
示例#9
0
        protected override bool SocketIocpError(int error, RioConnectionOrientedSocket socket, byte status)
        {
            if (error == Kernel32.ERROR_ABANDONED_WAIT_0)
            {
                return(true);
            }
            else if (error == Kernel32.ERROR_NETNAME_DELETED)
            {
                BeginRecycle(socket, false);
            }
            else
            {
                throw new Win32Exception(error);
            }

            return(false);
        }
示例#10
0
        protected override bool SocketIocpError(int error, RioConnectionOrientedSocket socket, byte status)
        {
            if (error == Kernel32.ERROR_ABANDONED_WAIT_0)
                return true;
            else if (error == Kernel32.ERROR_NETNAME_DELETED || error == Kernel32.ERROR_CONNECTION_REFUSED || error == 52)
            {
                TaskCompletionSource<RioSocket> r;
                BeginRecycle(socket,false);
                if (_ongoingConnections.TryRemove(socket, out r))
                    ThreadPool.QueueUserWorkItem(oo =>
                    {
                        var rr = (Tuple<TaskCompletionSource<RioSocket>, int>)oo;
                        rr.Item1.SetException(new Win32Exception(rr.Item2));
                    }, Tuple.Create(r, error));
            }
            else
                throw new Win32Exception(error);

            return false;
        }
示例#11
0
        internal unsafe virtual void BeginRecycle(RioConnectionOrientedSocket socket, bool force)
        {
            RioConnectionOrientedSocket c;

            activeSockets.TryRemove(socket.GetHashCode(), out c);

            if (force || socket.Socket == IntPtr.Zero || socket.pendingRecives > 0 || socket.pendingSends > 0)
            {
                socket.ResetSocket();
                if ((Kernel32.CreateIoCompletionPort(socket.Socket, socketIocp, 0, 1)) == IntPtr.Zero)
                {
                    Kernel32.ThrowLastError();
                }
                InitializeSocket(socket);
                EndRecycle(socket, false);
            }
            else
            {
                disconnectingSockets.TryAdd(socket.GetHashCode(), socket);
                socket.disconnectStartTime = CurrentTime;

                socket._overlapped->Status = 1;
                if (!RioStatic.DisconnectEx(socket.Socket, socket._overlapped, WinSock.TF_REUSE_SOCKET, 0))
                {
                    var error = WinSock.WSAGetLastError();
                    if (error == WinSock.WSAENOTCONN || error == 10038)
                    {
                        BeginRecycle(socket, true);
                    }

                    else
                    {
                        WinSock.ThrowLastWSAError();
                    }
                }
            }
        }
示例#12
0
        public unsafe RioConnectionOrientedSocketPool(RioFixedBufferPool sendPool, RioFixedBufferPool revicePool, uint socketCount, ADDRESS_FAMILIES adressFam, SOCKET_TYPE sockType, PROTOCOL protocol,
                                                      uint maxOutstandingReceive = 1024, uint maxOutstandingSend = 1024)
            : base(sendPool, revicePool, adressFam, sockType, protocol, maxOutstandingReceive, maxOutstandingSend, socketCount)
        {
            var adrSize      = (sizeof(sockaddr_in) + 16) * 2;
            var overlapped   = Marshal.AllocHGlobal(new IntPtr(socketCount * Marshal.SizeOf <RioNativeOverlapped>()));
            var adressBuffer = Marshal.AllocHGlobal(new IntPtr(socketCount * adrSize));

            allSockets = new RioConnectionOrientedSocket[socketCount];
            var inc = ulong.MaxValue / socketCount;

            for (int i = 0; i < socketCount; i++)
            {
                allSockets[i] = new RioConnectionOrientedSocket(inc * (ulong)i, overlapped + (i * Marshal.SizeOf <RioNativeOverlapped>()), adressBuffer + (i * adrSize), this, SendBufferPool, ReceiveBufferPool, adressBufferPool, maxOutstandingReceive, maxOutstandingSend, SendCompletionQueue, ReceiveCompletionQueue, adressFam, sockType, protocol);
                allSockets[i]._overlapped->SocketIndex = i;
            }

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

            foreach (var s in allSockets)
            {
                if ((Kernel32.CreateIoCompletionPort(s.Socket, socketIocp, 0, 1)) == IntPtr.Zero)
                {
                    Kernel32.ThrowLastError();
                }
            }

            Thread SocketIocpThread = new Thread(SocketIocpComplete);

            SocketIocpThread.IsBackground = true;
            SocketIocpThread.Start();

            Timeout();
        }
示例#13
0
 internal abstract void InitializeSocket(RioConnectionOrientedSocket socket);
示例#14
0
 internal abstract void FinalizeRecycle(RioConnectionOrientedSocket socket);
示例#15
0
 internal override void FinalizeRecycle(RioConnectionOrientedSocket socket)
 {
     _freeSockets.Enqueue(socket);
 }
示例#16
0
 internal override void FinalizeRecycle(RioConnectionOrientedSocket socket)
 {
     _freeSockets.Enqueue(socket);
 }
        internal unsafe virtual void BeginRecycle(RioConnectionOrientedSocket socket, bool force)
        {
            RioConnectionOrientedSocket c;
            activeSockets.TryRemove(socket.GetHashCode(), out c);

            if (force || socket.Socket == IntPtr.Zero || socket.pendingRecives > 0 || socket.pendingSends > 0)
            {
                socket.ResetSocket();
                if ((Kernel32.CreateIoCompletionPort(socket.Socket, socketIocp, 0, 1)) == IntPtr.Zero)
                    Kernel32.ThrowLastError();
                InitializeSocket(socket);
                EndRecycle(socket, false);
            }
            else
            {
                disconnectingSockets.TryAdd(socket.GetHashCode(), socket);
                socket.disconnectStartTime = CurrentTime;

                socket._overlapped->Status = 1;
                if (!RioStatic.DisconnectEx(socket.Socket, socket._overlapped, WinSock.TF_REUSE_SOCKET, 0))
                {
                    var error = WinSock.WSAGetLastError();
                    if (error == WinSock.WSAENOTCONN || error == 10038)
                        BeginRecycle(socket, true);

                    else
                        WinSock.ThrowLastWSAError();
                }
            }
        }
示例#18
0
        protected override bool SocketIocpError(int error, RioConnectionOrientedSocket socket, byte status)
        {
            if (error == Kernel32.ERROR_ABANDONED_WAIT_0)
                return true;
            else if (error == Kernel32.ERROR_NETNAME_DELETED)
                BeginRecycle(socket,false);
            else
                throw new Win32Exception(error);

            return false;
        }
示例#19
0
 internal override void InitializeSocket(RioConnectionOrientedSocket socket)
 {
     var t = TimeSpan.FromSeconds(30);
     socket.SetLoopbackFastPath(true);
     socket.SetTcpNoDelay(true);
     socket.SendTimeout = t;
     socket.ReciveTimeout = t;
 }
示例#20
0
 internal override void FinalizeRecycle(RioConnectionOrientedSocket socket)
 {
     BeginAccept(socket);
 }
示例#21
0
 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))
     {
         WinSock.ThrowLastWSAError();
     }
     else
     {
         acceptSocket.SetInUse(true);
         OnAccepted(acceptSocket);
     }
 }
示例#22
0
        protected override bool SocketIocpOk(RioConnectionOrientedSocket socket, byte status)
        {
            ThreadPool.QueueUserWorkItem(oo =>
            {
                EndRecycle((RioConnectionOrientedSocket)oo, true);
            }, socket);

            return false;
        }
 internal abstract void InitializeSocket(RioConnectionOrientedSocket socket);
 internal void EndRecycle(RioConnectionOrientedSocket socket, bool async)
 {
     RioConnectionOrientedSocket s;
     disconnectingSockets.TryRemove(socket.GetHashCode(), out s);
     socket.pendingRecives = 0;
     socket.pendingSends = 0;
     FinalizeRecycle(socket);
 }
 internal abstract void FinalizeRecycle(RioConnectionOrientedSocket socket);
 protected abstract bool SocketIocpError(int error, RioConnectionOrientedSocket socket, byte status);
示例#27
0
 protected abstract bool SocketIocpOk(RioConnectionOrientedSocket socket, byte status);
 protected abstract bool SocketIocpOk(RioConnectionOrientedSocket socket, byte status);
示例#29
0
 protected abstract bool SocketIocpError(int error, RioConnectionOrientedSocket socket, byte status);
示例#30
0
        static async Task ServeFixed(RioConnectionOrientedSocket socket)
        {
            try
            {
                var buffer = new byte[128 * pipeLineDeph];
                var leftoverLength = 0;
                var oldleftoverLength = 0;
                uint endOfRequest = 0x0a0d0a0d;
                uint current = 0;
                var stream = new RioStream(socket);

                while (true)
                {
                    int r = await stream.ReadAsync(buffer, 0, buffer.Length);
                    if (r == 0)
                        break;


                    for (int i = 0; leftoverLength != 0 && i < 4 - leftoverLength; i++)
                    {
                        current += buffer[i];
                        current = current << 8;
                        if (current == endOfRequest)
                            socket.WritePreAllocated(currentSegment);
                    }

                    leftoverLength = r % 4;
                    var length = r - leftoverLength;

                    unsafe
                    {
                        fixed (byte* currentPtr = &buffer[oldleftoverLength])
                        {
                            var start = currentPtr;
                            var end = currentPtr + length;

                            for (; start <= end; start++)
                            {
                                if (*(uint*)start == endOfRequest)
                                    socket.WritePreAllocated(currentSegment);
                            }
                        }
                    }

                    oldleftoverLength = leftoverLength;

                    for (int i = r - leftoverLength; i < r; i++)
                    {
                        current += buffer[i];
                        current = current << 4;
                    }
                    stream.Flush();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            finally
            {
                socket.Dispose();
            }
        }
示例#31
0
 internal override void FinalizeRecycle(RioConnectionOrientedSocket socket)
 {
     BeginAccept(socket);
 }