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); } }
internal static int ThrowLastWSAError() { var error = WinSock.WSAGetLastError(); if (error != 0) { throw new Win32Exception(error); } else { return(error); } }
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); } }
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); }