public static unsafe SocketError Send(SafeCloseSocket handle, byte[] buffer, int offset, int size, SocketFlags socketFlags, out int bytesTransferred) { int bytesSent; if (buffer.Length == 0) { bytesSent = Interop.Winsock.send(handle.DangerousGetHandle(), null, 0, socketFlags); } else { fixed(byte *pinnedBuffer = buffer) { bytesSent = Interop.Winsock.send( handle.DangerousGetHandle(), pinnedBuffer + offset, size, socketFlags); } } if (bytesSent == (int)SocketError.SocketError) { bytesTransferred = 0; return(GetLastSocketError()); } bytesTransferred = bytesSent; return(SocketError.Success); }
public static unsafe SocketError ReceiveFrom(SafeCloseSocket handle, byte[] buffer, int offset, int size, SocketFlags socketFlags, byte[] socketAddress, ref int addressLength, out int bytesTransferred) { int bytesReceived; if (buffer.Length == 0) { bytesReceived = Interop.Winsock.recvfrom(handle.DangerousGetHandle(), null, 0, socketFlags, socketAddress, ref addressLength); } else { fixed(byte *pinnedBuffer = buffer) { bytesReceived = Interop.Winsock.recvfrom(handle.DangerousGetHandle(), pinnedBuffer + offset, size, socketFlags, socketAddress, ref addressLength); } } if (bytesReceived == (int)SocketError.SocketError) { bytesTransferred = 0; return(GetLastSocketError()); } bytesTransferred = bytesReceived; return(SocketError.Success); }
public static unsafe SocketError ReceiveAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, OverlappedAsyncResult asyncResult) { // Set up asyncResult for overlapped WSARecv. asyncResult.SetUnmanagedStructures(buffer, offset, count, null); try { int bytesTransferred; SocketError errorCode = Interop.Winsock.WSARecv( handle.DangerousGetHandle(), // to minimize chances of handle recycling from misuse, this should use DangerousAddRef/Release, but it adds too much overhead ref asyncResult._singleBuffer, 1, out bytesTransferred, ref socketFlags, asyncResult.DangerousOverlappedPointer, // SafeHandle was just created in SetUnmanagedStructures IntPtr.Zero); GC.KeepAlive(handle); // small extra safe guard against handle getting collected/finalized while P/Invoke in progress return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred)); } catch { asyncResult.ReleaseUnmanagedStructures(); throw; } }
public static unsafe SocketError SendAsync(SafeCloseSocket handle, IList <ArraySegment <byte> > buffers, SocketFlags socketFlags, OverlappedAsyncResult asyncResult) { // Set up asyncResult for overlapped WSASend. asyncResult.SetUnmanagedStructures(buffers); try { int bytesTransferred; SocketError errorCode = Interop.Winsock.WSASend( handle.DangerousGetHandle(), // to minimize chances of handle recycling from misuse, this should use DangerousAddRef/Release, but it adds too much overhead asyncResult._wsaBuffers, asyncResult._wsaBuffers.Length, out bytesTransferred, socketFlags, asyncResult.DangerousOverlappedPointer, // SafeHandle was just created in SetUnmanagedStructures IntPtr.Zero); GC.KeepAlive(handle); // small extra safe guard against handle getting collected/finalized while P/Invoke in progress return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred)); } catch { asyncResult.ReleaseUnmanagedStructures(); throw; } }
public static SocketError ReceiveMessageFrom(Socket socket, SafeCloseSocket handle, byte[] buffer, int offset, int size, ref SocketFlags socketFlags, Internals.SocketAddress socketAddress, out Internals.SocketAddress receiveAddress, out IPPacketInformation ipPacketInformation, out int bytesTransferred) { ReceiveMessageOverlappedAsyncResult asyncResult = new ReceiveMessageOverlappedAsyncResult(socket, null, null); asyncResult.SetUnmanagedStructures(buffer, offset, size, socketAddress, socketFlags); SocketError errorCode = SocketError.Success; bytesTransferred = 0; try { // This can throw ObjectDisposedException (retrieving the delegate AND resolving the handle). if (socket.WSARecvMsgBlocking( handle.DangerousGetHandle(), Marshal.UnsafeAddrOfPinnedArrayElement(asyncResult._messageBuffer, 0), out bytesTransferred, IntPtr.Zero, IntPtr.Zero) == SocketError.SocketError) { errorCode = (SocketError)Marshal.GetLastWin32Error(); } } finally { asyncResult.SyncReleaseUnmanagedStructures(); } socketFlags = asyncResult.SocketFlags; receiveAddress = asyncResult.SocketAddress; ipPacketInformation = asyncResult.IPPacketInformation; return(errorCode); }
internal static InnerSafeCloseSocket Accept(SafeCloseSocket socketHandle, byte[] socketAddress, ref int socketAddressSize) { InnerSafeCloseSocket result = Interop.Winsock.accept(socketHandle.DangerousGetHandle(), socketAddress, ref socketAddressSize); if (result.IsInvalid) { result.SetHandleAsInvalid(); } return(result); }
public static SocketError Receive(SafeCloseSocket handle, IList <ArraySegment <byte> > buffers, ref SocketFlags socketFlags, out int bytesTransferred) { int count = buffers.Count; WSABuffer[] WSABuffers = new WSABuffer[count]; GCHandle[] objectsToPin = null; try { objectsToPin = new GCHandle[count]; for (int i = 0; i < count; ++i) { ArraySegment <byte> buffer = buffers[i]; RangeValidationHelpers.ValidateSegment(buffer); objectsToPin[i] = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned); WSABuffers[i].Length = buffer.Count; WSABuffers[i].Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffer.Array, buffer.Offset); } // This can throw ObjectDisposedException. unsafe { SocketError errorCode = Interop.Winsock.WSARecv( handle.DangerousGetHandle(), WSABuffers, count, out bytesTransferred, ref socketFlags, null, IntPtr.Zero); if (errorCode == SocketError.SocketError) { errorCode = GetLastSocketError(); } return(errorCode); } } finally { if (objectsToPin != null) { for (int i = 0; i < objectsToPin.Length; ++i) { if (objectsToPin[i].IsAllocated) { objectsToPin[i].Free(); } } } } }
public static SocketError Disconnect(Socket socket, SafeCloseSocket handle, bool reuseSocket) { SocketError errorCode = SocketError.Success; // This can throw ObjectDisposedException (handle, and retrieving the delegate). if (!socket.DisconnectExBlocking(handle.DangerousGetHandle(), IntPtr.Zero, (int)(reuseSocket ? TransmitFileOptions.ReuseSocket : 0), 0)) { errorCode = GetLastSocketError(); } return(errorCode); }
public static SocketError Connect(SafeCloseSocket handle, byte[] peerAddress, int peerAddressLen) { SocketError errorCode = Interop.Winsock.WSAConnect( handle.DangerousGetHandle(), peerAddress, peerAddressLen, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); return(errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success); }
public static SocketError Send(SafeCloseSocket handle, BufferOffsetSize[] buffers, SocketFlags socketFlags, out int bytesTransferred) { WSABuffer[] WSABuffers = new WSABuffer[buffers.Length]; GCHandle[] objectsToPin = null; try { objectsToPin = new GCHandle[buffers.Length]; for (int i = 0; i < buffers.Length; ++i) { objectsToPin[i] = GCHandle.Alloc(buffers[i].Buffer, GCHandleType.Pinned); WSABuffers[i].Length = buffers[i].Size; WSABuffers[i].Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffers[i].Buffer, buffers[i].Offset); } // This can throw ObjectDisposedException. SocketError errorCode = Interop.Winsock.WSASend_Blocking( handle.DangerousGetHandle(), WSABuffers, WSABuffers.Length, out bytesTransferred, socketFlags, SafeNativeOverlapped.Zero, IntPtr.Zero); if (errorCode == SocketError.SocketError) { errorCode = (SocketError)Marshal.GetLastWin32Error(); } return(errorCode); } finally { if (objectsToPin != null) { for (int i = 0; i < objectsToPin.Length; ++i) { if (objectsToPin[i].IsAllocated) { objectsToPin[i].Free(); } } } } }
public bool TryRegister(SafeCloseSocket socket, Interop.Sys.SocketEvents current, Interop.Sys.SocketEvents events, GCHandle handle, out Interop.Error error) { if (current == events) { error = Interop.Error.SUCCESS; return(true); } // // @TODO: work out a better way to handle this. For now, just do the "dangerous" thing; this is called // from SafeCloseSocket.ReleaseHandle, so it can't access the file descriptor in the normal way. // int fd = (int)socket.DangerousGetHandle(); error = Interop.Sys.DangerousTryChangeSocketEventRegistration(_port, fd, current, events, (IntPtr)handle); return(error == Interop.Error.SUCCESS); }
public static unsafe SocketError Send(SafeCloseSocket handle, ReadOnlySpan <byte> buffer, SocketFlags socketFlags, out int bytesTransferred) { int bytesSent; fixed(byte *bufferPtr = &MemoryMarshal.GetReference(buffer)) { bytesSent = Interop.Winsock.send(handle.DangerousGetHandle(), bufferPtr, buffer.Length, socketFlags); } if (bytesSent == (int)SocketError.SocketError) { bytesTransferred = 0; return(GetLastSocketError()); } bytesTransferred = bytesSent; return(SocketError.Success); }
public static unsafe SocketError Receive(SafeCloseSocket handle, Span <byte> buffer, SocketFlags socketFlags, out int bytesTransferred) { int bytesReceived; fixed(byte *bufferPtr = &buffer.DangerousGetPinnableReference()) { bytesReceived = Interop.Winsock.recv(handle.DangerousGetHandle(), bufferPtr, buffer.Length, socketFlags); } if (bytesReceived == (int)SocketError.SocketError) { bytesTransferred = 0; return(GetLastSocketError()); } bytesTransferred = bytesReceived; return(SocketError.Success); }
public static SocketError Poll(SafeCloseSocket handle, int microseconds, SelectMode mode, out bool status) { IntPtr rawHandle = handle.DangerousGetHandle(); IntPtr[] fileDescriptorSet = new IntPtr[2] { (IntPtr)1, rawHandle }; Interop.Winsock.TimeValue IOwait = new Interop.Winsock.TimeValue(); // A negative timeout value implies an indefinite wait. int socketCount; if (microseconds != -1) { MicrosecondsToTimeValue((long)(uint)microseconds, ref IOwait); socketCount = Interop.Winsock.select( 0, mode == SelectMode.SelectRead ? fileDescriptorSet : null, mode == SelectMode.SelectWrite ? fileDescriptorSet : null, mode == SelectMode.SelectError ? fileDescriptorSet : null, ref IOwait); } else { socketCount = Interop.Winsock.select( 0, mode == SelectMode.SelectRead ? fileDescriptorSet : null, mode == SelectMode.SelectWrite ? fileDescriptorSet : null, mode == SelectMode.SelectError ? fileDescriptorSet : null, IntPtr.Zero); } if ((SocketError)socketCount == SocketError.SocketError) { status = false; return(GetLastSocketError()); } status = (int)fileDescriptorSet[0] != 0 && fileDescriptorSet[1] == rawHandle; return(SocketError.Success); }
public static SocketError WindowsIoctl(SafeCloseSocket handle, int ioControlCode, byte[] optionInValue, byte[] optionOutValue, out int optionLength) { if (ioControlCode == Interop.Winsock.IoctlSocketConstants.FIONBIO) { throw new InvalidOperationException(SR.net_sockets_useblocking); } SocketError errorCode = Interop.Winsock.WSAIoctl_Blocking( handle.DangerousGetHandle(), ioControlCode, optionInValue, optionInValue != null ? optionInValue.Length : 0, optionOutValue, optionOutValue != null ? optionOutValue.Length : 0, out optionLength, SafeNativeOverlapped.Zero, IntPtr.Zero); return(errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success); }
public static SocketError IoctlInternal(SafeCloseSocket handle, IOControlCode ioControlCode, IntPtr optionInValue, int inValueLength, IntPtr optionOutValue, int outValueLength, out int optionLength) { if ((unchecked ((int)ioControlCode)) == Interop.Winsock.IoctlSocketConstants.FIONBIO) { throw new InvalidOperationException(SR.net_sockets_useblocking); } SocketError errorCode = Interop.Winsock.WSAIoctl_Blocking_Internal( handle.DangerousGetHandle(), (uint)ioControlCode, optionInValue, inValueLength, optionOutValue, outValueLength, out optionLength, SafeNativeOverlapped.Zero, IntPtr.Zero); return(errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success); }
internal static InnerSafeCloseSocket Accept(SafeCloseSocket socketHandle, byte[] socketAddress, ref int socketAddressSize) { InnerSafeCloseSocket result = Interop.Winsock.accept(socketHandle.DangerousGetHandle(), socketAddress, ref socketAddressSize); if (result.IsInvalid) { result.SetHandleAsInvalid(); } return result; }
public static unsafe SocketError Poll(SafeCloseSocket handle, int microseconds, SelectMode mode, out bool status) { uint* fdSet = stackalloc uint[Interop.Sys.FD_SETSIZE_UINTS]; Interop.Sys.FD_ZERO(fdSet); bool releaseHandle = false; try { handle.DangerousAddRef(ref releaseHandle); int fd = (int)handle.DangerousGetHandle(); Interop.Sys.FD_SET(fd, fdSet); int fdCount = 0; uint* readFds = null; uint* writeFds = null; uint* errorFds = null; switch (mode) { case SelectMode.SelectRead: readFds = fdSet; fdCount = fd + 1; break; case SelectMode.SelectWrite: writeFds = fdSet; fdCount = fd + 1; break; case SelectMode.SelectError: errorFds = fdSet; fdCount = fd + 1; break; } int socketCount = 0; Interop.Error err = Interop.Sys.Select(fdCount, readFds, writeFds, errorFds, microseconds, &socketCount); if (err != Interop.Error.SUCCESS) { status = false; return GetSocketErrorForErrorCode(err); } status = Interop.Sys.FD_ISSET(fd, fdSet); } finally { if (releaseHandle) { handle.DangerousRelease(); } } return SocketError.Success; }
public static unsafe SocketError ReceiveMessageFrom(Socket socket, SafeCloseSocket handle, byte[] buffer, int offset, int size, ref SocketFlags socketFlags, Internals.SocketAddress socketAddress, out Internals.SocketAddress receiveAddress, out IPPacketInformation ipPacketInformation, out int bytesTransferred) { bool ipv4, ipv6; Socket.GetIPProtocolInformation(socket.AddressFamily, socketAddress, out ipv4, out ipv6); bytesTransferred = 0; receiveAddress = socketAddress; ipPacketInformation = default(IPPacketInformation); fixed(byte *ptrBuffer = buffer) fixed(byte *ptrSocketAddress = socketAddress.Buffer) { Interop.Winsock.WSAMsg wsaMsg; wsaMsg.socketAddress = (IntPtr)ptrSocketAddress; wsaMsg.addressLength = (uint)socketAddress.Size; wsaMsg.flags = socketFlags; WSABuffer wsaBuffer; wsaBuffer.Length = size; wsaBuffer.Pointer = (IntPtr)(ptrBuffer + offset); wsaMsg.buffers = (IntPtr)(&wsaBuffer); wsaMsg.count = 1; if (ipv4) { Interop.Winsock.ControlData controlBuffer; wsaMsg.controlBuffer.Pointer = (IntPtr)(&controlBuffer); wsaMsg.controlBuffer.Length = sizeof(Interop.Winsock.ControlData); if (socket.WSARecvMsgBlocking( handle.DangerousGetHandle(), (IntPtr)(&wsaMsg), out bytesTransferred, IntPtr.Zero, IntPtr.Zero) == SocketError.SocketError) { return(GetLastSocketError()); } ipPacketInformation = GetIPPacketInformation(&controlBuffer); } else if (ipv6) { Interop.Winsock.ControlDataIPv6 controlBuffer; wsaMsg.controlBuffer.Pointer = (IntPtr)(&controlBuffer); wsaMsg.controlBuffer.Length = sizeof(Interop.Winsock.ControlDataIPv6); if (socket.WSARecvMsgBlocking( handle.DangerousGetHandle(), (IntPtr)(&wsaMsg), out bytesTransferred, IntPtr.Zero, IntPtr.Zero) == SocketError.SocketError) { return(GetLastSocketError()); } ipPacketInformation = GetIPPacketInformation(&controlBuffer); } else { wsaMsg.controlBuffer.Pointer = IntPtr.Zero; wsaMsg.controlBuffer.Length = 0; if (socket.WSARecvMsgBlocking( handle.DangerousGetHandle(), (IntPtr)(&wsaMsg), out bytesTransferred, IntPtr.Zero, IntPtr.Zero) == SocketError.SocketError) { return(GetLastSocketError()); } } socketFlags = wsaMsg.flags; } return(SocketError.Success); }