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(); }
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); }
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); }
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); }
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); } }
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); }
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; }
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(); } } } }
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(); }
internal abstract void InitializeSocket(RioConnectionOrientedSocket socket);
internal abstract void FinalizeRecycle(RioConnectionOrientedSocket socket);
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(); } } }
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; }
internal override void InitializeSocket(RioConnectionOrientedSocket socket) { var t = TimeSpan.FromSeconds(30); socket.SetLoopbackFastPath(true); socket.SetTcpNoDelay(true); socket.SendTimeout = t; socket.ReciveTimeout = t; }
internal override void FinalizeRecycle(RioConnectionOrientedSocket socket) { BeginAccept(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)) { WinSock.ThrowLastWSAError(); } else { acceptSocket.SetInUse(true); OnAccepted(acceptSocket); } }
protected override bool SocketIocpOk(RioConnectionOrientedSocket socket, byte status) { ThreadPool.QueueUserWorkItem(oo => { EndRecycle((RioConnectionOrientedSocket)oo, true); }, socket); return false; }
internal void EndRecycle(RioConnectionOrientedSocket socket, bool async) { RioConnectionOrientedSocket s; disconnectingSockets.TryRemove(socket.GetHashCode(), out s); socket.pendingRecives = 0; socket.pendingSends = 0; FinalizeRecycle(socket); }
protected abstract bool SocketIocpError(int error, RioConnectionOrientedSocket socket, byte status);
protected abstract bool SocketIocpOk(RioConnectionOrientedSocket socket, byte status);
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(); } }