diff --git a/PInvoke/Ws2_32/WinSock2.WSA.Error.cs b/PInvoke/Ws2_32/WinSock2.WSA.Error.cs
index 31a89aad..e7f9ff8b 100644
--- a/PInvoke/Ws2_32/WinSock2.WSA.Error.cs
+++ b/PInvoke/Ws2_32/WinSock2.WSA.Error.cs
@@ -51,6 +51,11 @@ public static partial class Ws2_32
/// The result of the conversion.
public static implicit operator WSRESULT(SocketError value) => new((int)value);
+ /// Implements the operator !.
+ /// The value.
+ /// The result of the operator.
+ public static bool operator !(WSRESULT value) => value.Failed;
+
/// Implements the operator !=.
/// The first .
/// The second .
@@ -81,14 +86,21 @@ public static partial class Ws2_32
///
/// The 32-bit raw WSRESULT value.
/// The optional message to assign to the .
+ [SecurityCritical, System.Diagnostics.DebuggerStepThrough]
public static void ThrowIfFailed(int value, string message = null) => new WSRESULT(value).ThrowIfFailed(message);
+ /// Throws the last error.
+ /// The message.
+ [SecurityCritical, System.Diagnostics.DebuggerStepThrough]
+ public static void ThrowLastError(string message = null) => GetLastError().ThrowIfFailed(message);
+
/// Throws the last error if the predicate delegate returns .
/// The type of the value to evaluate.
/// The value to check.
/// The delegate which returns on failure.
/// The message.
/// The passed in on success.
+ [SecurityCritical, System.Diagnostics.DebuggerStepThrough]
public static T ThrowLastErrorIf(T value, Func valueIsFailure, string message = null)
{
if (valueIsFailure(value))
@@ -99,11 +111,13 @@ public static partial class Ws2_32
/// Throws the last error if the function returns .
/// The value to check.
/// The message.
+ [SecurityCritical, System.Diagnostics.DebuggerStepThrough]
public static bool ThrowLastErrorIfFalse(bool value, string message = null) => ThrowLastErrorIf(value, v => !v, message);
/// Throws the last error if the value is an invalid handle.
/// The SafeHandle to check.
/// The message.
+ [SecurityCritical, System.Diagnostics.DebuggerStepThrough]
public static T ThrowLastErrorIfInvalid(T value, string message = null) where T : SafeHandle => ThrowLastErrorIf(value, v => v.IsInvalid, message);
/// Compares the current object with another object of the same type.
@@ -180,16 +194,14 @@ public static partial class Ws2_32
/// Gets the last error.
/// The last error.
- [SecurityCritical]
- [System.Diagnostics.DebuggerStepThrough]
+ [SecurityCritical, System.Diagnostics.DebuggerStepThrough]
public static WSRESULT GetLastError() => WSAGetLastError();
///
/// If this represents a failure, throw the associated with the optionally supplied message.
///
/// The optional message to assign to the .
- [SecurityCritical]
- [SecuritySafeCritical]
+ [SecurityCritical, SecuritySafeCritical, System.Diagnostics.DebuggerStepThrough]
public void ThrowIfFailed(string message = null)
{
Exception exception = GetException(message);
@@ -240,6 +252,55 @@ public static partial class Ws2_32
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)unchecked((uint)_value)).ToUInt64(provider);
+ ///
+ /// Specified event object handle is invalid.
+ /// An application attempts to use an event object, but the specified handle is not valid.
+ ///
+ public const int WSA_INVALID_HANDLE = 6;
+
+ ///
+ /// Insufficient memory available.
+ ///
+ /// An application used a Windows Sockets function that directly maps to a Windows function. The Windows function is indicating a
+ /// lack of required memory resources.
+ ///
+ ///
+ public const int WSA_NOT_ENOUGH_MEMORY = 8;
+
+ ///
+ /// One or more parameters are invalid.
+ ///
+ /// An application used a Windows Sockets function which directly maps to a Windows function. The Windows function is indicating a
+ /// problem with one or more parameters.
+ ///
+ ///
+ public const int WSA_INVALID_PARAMETER = 87;
+
+ ///
+ /// Overlapped operation aborted.
+ /// An overlapped operation was canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSAIoctl.
+ ///
+ public const int WSA_OPERATION_ABORTED = 995;
+
+ ///
+ /// Overlapped I/O event object not in signaled state.
+ ///
+ /// The application has tried to determine the status of an overlapped operation which is not yet completed. Applications that use
+ /// WSAGetOverlappedResult (with the fWait flag set to FALSE) in a polling mode to determine when an overlapped operation has
+ /// completed, get this error code until the operation is complete.
+ ///
+ ///
+ public const int WSA_IO_INCOMPLETE = 996;
+
+ ///
+ /// Overlapped operations will complete later.
+ ///
+ /// The application has initiated an overlapped operation that cannot be completed immediately. A completion indication will be given
+ /// later when the operation has been completed.
+ ///
+ ///
+ public const int WSA_IO_PENDING = 997;
+
/// A blocking operation was interrupted by a call to WSACancelBlockingCall.
public const int WSAEINTR = 0x00002714;
diff --git a/PInvoke/Ws2_32/WinSock2.WSA.cs b/PInvoke/Ws2_32/WinSock2.WSA.cs
index e914cb7b..04541016 100644
--- a/PInvoke/Ws2_32/WinSock2.WSA.cs
+++ b/PInvoke/Ws2_32/WinSock2.WSA.cs
@@ -2930,7 +2930,7 @@ namespace Vanara.PInvoke
// WSAEnumNameSpaceProvidersW( LPDWORD lpdwBufferLength, LPWSANAMESPACE_INFOW lpnspBuffer );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Unicode)]
[PInvokeData("winsock2.h", MSDNShortId = "f5b6cd42-c5cb-43b6-bb96-fd260217e252")]
- public static extern WSRESULT WSAEnumNameSpaceProviders(ref uint lpdwBufferLength, [Out] IntPtr lpnspBuffer);
+ public static extern int WSAEnumNameSpaceProviders(ref uint lpdwBufferLength, [Out] IntPtr lpnspBuffer);
/// The WSAEnumNameSpaceProvidersEx function retrieves information on available namespace providers.
///
@@ -3004,7 +3004,7 @@ namespace Vanara.PInvoke
// WSAEnumNameSpaceProvidersExA( LPDWORD lpdwBufferLength, LPWSANAMESPACE_INFOEXA lpnspBuffer );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Unicode)]
[PInvokeData("winsock2.h", MSDNShortId = "34bc96aa-63f7-4ab8-9376-6f4b979225ca")]
- public static extern WSRESULT WSAEnumNameSpaceProvidersEx(ref uint lpdwBufferLength, [Out] IntPtr lpnspBuffer);
+ public static extern int WSAEnumNameSpaceProvidersEx(ref uint lpdwBufferLength, [Out] IntPtr lpnspBuffer);
///
/// The WSAEnumNetworkEvents function discovers occurrences of network events for the indicated socket, clear internal
@@ -3278,7 +3278,7 @@ namespace Vanara.PInvoke
// lpiProtocols, LPWSAPROTOCOL_INFOA lpProtocolBuffer, LPDWORD lpdwBufferLength );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "928b6937-41a3-4268-a3bc-14c9e04870e4")]
- public static extern WSRESULT WSAEnumProtocols([Optional, MarshalAs(UnmanagedType.LPArray)] int[] lpiProtocols, [Out] IntPtr lpProtocolBuffer, ref uint lpdwBufferLength);
+ public static extern int WSAEnumProtocols([Optional, MarshalAs(UnmanagedType.LPArray)] int[] lpiProtocols, [Out] IntPtr lpProtocolBuffer, ref uint lpdwBufferLength);
///
/// The WSAEventSelect function specifies an event object to be associated with the specified set of FD_XXX network events.
@@ -5912,7 +5912,7 @@ namespace Vanara.PInvoke
// fds, INT timeout );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "3f6f872c-5cee-49f3-bf22-2e8a5d147987")]
- public static extern WSRESULT WSAPoll([In, Out, MarshalAs(UnmanagedType.LPArray)] WSAPOLLFD[] fdArray, uint fds, int timeout);
+ public static extern int WSAPoll([In, Out, MarshalAs(UnmanagedType.LPArray)] WSAPOLLFD[] fdArray, uint fds, int timeout);
/// The WSAProviderConfigChange function notifies the application when the provider configuration is changed.
///
diff --git a/PInvoke/Ws2_32/WinSock2.cs b/PInvoke/Ws2_32/WinSock2.cs
index e1ab46ec..dfe32e93 100644
--- a/PInvoke/Ws2_32/WinSock2.cs
+++ b/PInvoke/Ws2_32/WinSock2.cs
@@ -1295,29 +1295,35 @@ namespace Vanara.PInvoke
/// Gets or sets the byte array representing the IPv6 address.
/// The bytes.
/// Byte array must have 16 items. - value
- public unsafe byte[] bytes
+ public byte[] bytes
{
get
{
- var v6addr = new byte[IN6_ADDR_SIZE];
- fixed (byte* usp = &v6addr[0])
+ unsafe
{
- var ulp2 = (ulong*)usp;
- ulp2[0] = lower;
- ulp2[1] = upper;
+ var v6addr = new byte[IN6_ADDR_SIZE];
+ fixed (byte* usp = &v6addr[0])
+ {
+ var ulp2 = (ulong*)usp;
+ ulp2[0] = lower;
+ ulp2[1] = upper;
+ }
+ return v6addr;
}
- return v6addr;
}
set
{
- if (value == null) value = new byte[IN6_ADDR_SIZE];
- if (value.Length != IN6_ADDR_SIZE)
- throw new ArgumentException("Byte array must have 16 items.", nameof(value));
- fixed (byte* bp = &value[0])
+ unsafe
{
- var ulp = (ulong*)bp;
- lower = ulp[0];
- upper = ulp[1];
+ if (value == null) value = new byte[IN6_ADDR_SIZE];
+ if (value.Length != IN6_ADDR_SIZE)
+ throw new ArgumentException("Byte array must have 16 items.", nameof(value));
+ fixed (byte* bp = &value[0])
+ {
+ var ulp = (ulong*)bp;
+ lower = ulp[0];
+ upper = ulp[1];
+ }
}
}
}
@@ -1325,29 +1331,35 @@ namespace Vanara.PInvoke
/// Gets or sets the array of WORD (ushort) values representing the IPv6 address.
/// The array of WORD values.
/// UInt16 array must have 8 items. - value
- public unsafe ushort[] words
+ public ushort[] words
{
get
{
- var v6addr = new ushort[IN6_ADDR_SIZE / 2];
- fixed (ushort* usp = &v6addr[0])
+ unsafe
{
- var ulp2 = (ulong*)usp;
- ulp2[0] = lower;
- ulp2[1] = upper;
+ var v6addr = new ushort[IN6_ADDR_SIZE / 2];
+ fixed (ushort* usp = &v6addr[0])
+ {
+ var ulp2 = (ulong*)usp;
+ ulp2[0] = lower;
+ ulp2[1] = upper;
+ }
+ return v6addr;
}
- return v6addr;
}
set
{
- if (value == null) value = new ushort[IN6_ADDR_SIZE / 2];
- if (value.Length != IN6_ADDR_SIZE / 2)
- throw new ArgumentException("UInt16 array must have 8 items.", nameof(value));
- fixed (ushort* bp = &value[0])
+ unsafe
{
- var ulp = (ulong*)bp;
- lower = ulp[0];
- upper = ulp[1];
+ if (value == null) value = new ushort[IN6_ADDR_SIZE / 2];
+ if (value.Length != IN6_ADDR_SIZE / 2)
+ throw new ArgumentException("UInt16 array must have 8 items.", nameof(value));
+ fixed (ushort* bp = &value[0])
+ {
+ var ulp = (ulong*)bp;
+ lower = ulp[0];
+ upper = ulp[1];
+ }
}
}
}
diff --git a/PInvoke/Ws2_32/WinSock2.legacy.cs b/PInvoke/Ws2_32/WinSock2.legacy.cs
index 6a838eaa..3023f548 100644
--- a/PInvoke/Ws2_32/WinSock2.legacy.cs
+++ b/PInvoke/Ws2_32/WinSock2.legacy.cs
@@ -169,7 +169,7 @@ namespace Vanara.PInvoke
// int *addrlen );
[DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "72246263-4806-4ab2-9b26-89a1782a954b")]
- public static extern SOCKET accept(SOCKET s, SOCKADDR addr, ref int addrlen);
+ public static extern SafeSOCKET accept(SOCKET s, SOCKADDR addr, ref int addrlen);
/// The accept function permits an incoming connection attempt on a socket.
///
@@ -313,7 +313,7 @@ namespace Vanara.PInvoke
// int *addrlen );
[DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "72246263-4806-4ab2-9b26-89a1782a954b")]
- public static extern SOCKET accept(SOCKET s, [Optional] IntPtr addr, [Optional] IntPtr addrlen);
+ public static extern SafeSOCKET accept(SOCKET s, [Optional] IntPtr addr, [Optional] IntPtr addrlen);
/// The bind function associates a local address with a socket.
/// A descriptor identifying an unbound socket.
@@ -2421,7 +2421,7 @@ namespace Vanara.PInvoke
// *argp );
[DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "048fcb8d-acd3-4917-a997-dd133db399f8")]
- public static extern WSRESULT ioctlsocket(SOCKET s, int cmd, IntPtr argp);
+ public static extern WSRESULT ioctlsocket(SOCKET s, uint cmd, IntPtr argp);
/// The listen function places a socket in a state in which it is listening for an incoming connection.
/// A descriptor identifying a bound, unconnected socket.
@@ -2818,7 +2818,207 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv int recv( SOCKET s, char *buf, int len, int flags );
[DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "8c247cd3-479f-45d0-a038-a24e80cc7c73")]
- public static extern WSRESULT recv(SOCKET s, IntPtr buf, int len, MsgFlags flags);
+ public static extern int recv(SOCKET s, IntPtr buf, int len, MsgFlags flags);
+
+ /// The recv function receives data from a connected socket or a bound connectionless socket.
+ /// The descriptor that identifies a connected socket.
+ /// A pointer to the buffer to receive the incoming data.
+ /// The length, in bytes, of the buffer pointed to by the buf parameter.
+ ///
+ /// A set of flags that influences the behavior of this function. See remarks below. See the Remarks section for details on the
+ /// possible value for this parameter.
+ ///
+ ///
+ ///
+ /// If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain
+ /// this data received. If the connection has been gracefully closed, the return value is zero.
+ ///
+ /// Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
+ ///
+ ///
+ /// Error code
+ /// Meaning
+ ///
+ /// -
+ /// WSANOTINITIALISED
+ /// A successful WSAStartup call must occur before using this function.
+ ///
+ /// -
+ /// WSAENETDOWN
+ /// The network subsystem has failed.
+ ///
+ /// -
+ /// WSAEFAULT
+ /// The buf parameter is not completely contained in a valid part of the user address space.
+ ///
+ /// -
+ /// WSAENOTCONN
+ /// The socket is not connected.
+ ///
+ /// -
+ /// WSAEINTR
+ /// The (blocking) call was canceled through WSACancelBlockingCall.
+ ///
+ /// -
+ /// WSAEINPROGRESS
+ /// A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
+ ///
+ /// -
+ /// WSAENETRESET
+ ///
+ /// For a connection-oriented socket, this error indicates that the connection has been broken due to keep-alive activity that
+ /// detected a failure while the operation was in progress. For a datagram socket, this error indicates that the time to live has expired.
+ ///
+ ///
+ /// -
+ /// WSAENOTSOCK
+ /// The descriptor is not a socket.
+ ///
+ /// -
+ /// WSAEOPNOTSUPP
+ ///
+ /// MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the
+ /// communication domain associated with this socket, or the socket is unidirectional and supports only send operations.
+ ///
+ ///
+ /// -
+ /// WSAESHUTDOWN
+ ///
+ /// The socket has been shut down; it is not possible to receive on a socket after shutdown has been invoked with how set to
+ /// SD_RECEIVE or SD_BOTH.
+ ///
+ ///
+ /// -
+ /// WSAEWOULDBLOCK
+ /// The socket is marked as nonblocking and the receive operation would block.
+ ///
+ /// -
+ /// WSAEMSGSIZE
+ /// The message was too large to fit into the specified buffer and was truncated.
+ ///
+ /// -
+ /// WSAEINVAL
+ ///
+ /// The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with
+ /// SO_OOBINLINE enabled or (for byte stream sockets only) len was zero or negative.
+ ///
+ ///
+ /// -
+ /// WSAECONNABORTED
+ ///
+ /// The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no
+ /// longer usable.
+ ///
+ ///
+ /// -
+ /// WSAETIMEDOUT
+ /// The connection has been dropped because of a network failure or because the peer system failed to respond.
+ ///
+ /// -
+ /// WSAECONNRESET
+ ///
+ /// The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket as
+ /// it is no longer usable. On a UDP-datagram socket, this error would indicate that a previous send operation resulted in an ICMP
+ /// "Port Unreachable" message.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The recv function is used to read incoming data on connection-oriented sockets, or connectionless sockets. When using a
+ /// connection-oriented protocol, the sockets must be connected before calling recv. When using a connectionless protocol,
+ /// the sockets must be bound before calling recv.
+ ///
+ ///
+ /// The local address of the socket must be known. For server applications, use an explicit bind function or an implicit accept or
+ /// WSAAccept function. Explicit binding is discouraged for client applications. For client applications, the socket can become
+ /// bound implicitly to a local address using connect, WSAConnect, sendto, WSASendTo, or WSAJoinLeaf.
+ ///
+ ///
+ /// For connected or connectionless sockets, the recv function restricts the addresses from which received messages are
+ /// accepted. The function only returns messages from the remote address specified in the connection. Messages from other addresses
+ /// are (silently) discarded.
+ ///
+ ///
+ /// For connection-oriented sockets (type SOCK_STREAM for example), calling recv will return as much data as is currently
+ /// available—up to the size of the buffer specified. If the socket has been configured for in-line reception of OOB data (socket
+ /// option SO_OOBINLINE) and OOB data is yet unread, only OOB data will be returned. The application can use the ioctlsocket or
+ /// WSAIoctl SIOCATMARK command to determine whether any more OOB data remains to be read.
+ ///
+ ///
+ /// For connectionless sockets (type SOCK_DGRAM or other message-oriented sockets), data is extracted from the first enqueued
+ /// datagram (message) from the destination address specified by the connect function.
+ ///
+ ///
+ /// If the datagram or message is larger than the buffer specified, the buffer is filled with the first part of the datagram, and
+ /// recv generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost; for reliable
+ /// protocols, the data is retained by the service provider until it is successfully read by calling recv with a large enough buffer.
+ ///
+ ///
+ /// If no incoming data is available at the socket, the recv call blocks and waits for data to arrive according to the
+ /// blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of
+ /// SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect functions can
+ /// be used to determine when more data arrives.
+ ///
+ ///
+ /// If the socket is connection oriented and the remote side has shut down the connection gracefully, and all data has been
+ /// received, a recv will complete immediately with zero bytes received. If the connection has been reset, a recv will
+ /// fail with the error WSAECONNRESET.
+ ///
+ ///
+ /// The flags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
+ /// associated socket. The semantics of this function are determined by the socket options and the flags parameter. The possible
+ /// value of flags parameter is constructed by using the bitwise OR operator with any of the following values.
+ ///
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// MSG_PEEK
+ ///
+ /// Peeks at the incoming data. The data is copied into the buffer, but is not removed from the input queue. The function
+ /// subsequently returns the amount of data that can be read in a single call to the recv (or recvfrom) function, which may not be
+ /// the same as the total amount of data queued on the socket. The amount of data that can actually be read in a single call to the
+ /// recv (or recvfrom) function is limited to the data size written in the send or sendto function call.
+ ///
+ ///
+ /// -
+ /// MSG_OOB
+ /// Processes Out Of Band (OOB) data.
+ ///
+ /// -
+ /// MSG_WAITALL
+ ///
+ /// The receive request will complete only when one of the following events occurs:Note that if the underlying transport does not
+ /// support MSG_WAITALL, or if the socket is in a non-blocking mode, then this call will fail with WSAEOPNOTSUPP. Also, if
+ /// MSG_WAITALL is specified along with MSG_OOB, MSG_PEEK, or MSG_PARTIAL, then this call will fail with WSAEOPNOTSUPP. This flag is
+ /// not supported on datagram sockets or message-oriented sockets.
+ ///
+ ///
+ ///
+ ///
+ /// Note When issuing a blocking Winsock call such as recv, Winsock may need to wait for a network event before the
+ /// call can complete. Winsock performs an alertable wait in this situation, which can be interrupted by an asynchronous procedure
+ /// call (APC) scheduled on the same thread. Issuing another blocking Winsock call inside an APC that interrupted an ongoing
+ /// blocking Winsock call on the same thread will lead to undefined behavior, and must never be attempted by Winsock clients.
+ ///
+ /// Example Code
+ /// The following code example shows the use of the recv function.
+ /// Example Code
+ /// For more information, and another example of the recv function, see Getting Started With Winsock.
+ /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later.
+ ///
+ /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows
+ /// Server 2012 R2, and later.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv int recv( SOCKET s, char *buf, int len, int flags );
+ [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("winsock.h", MSDNShortId = "8c247cd3-479f-45d0-a038-a24e80cc7c73")]
+ public static extern int recv(SOCKET s, byte[] buf, int len, MsgFlags flags);
/// The recvfrom function receives a datagram and stores the source address.
/// A descriptor identifying a bound socket.
@@ -3001,7 +3201,190 @@ namespace Vanara.PInvoke
// flags, sockaddr *from, int *fromlen );
[DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "3e4282e0-3ed0-43e7-9b27-72ec36b9cfa1")]
- public static extern WSRESULT recvfrom(SOCKET s, IntPtr buf, int len, int flags, SOCKADDR from, ref int fromlen);
+ public static extern int recvfrom(SOCKET s, IntPtr buf, int len, int flags, SOCKADDR from, ref int fromlen);
+
+ /// The recvfrom function receives a datagram and stores the source address.
+ /// A descriptor identifying a bound socket.
+ /// A buffer for the incoming data.
+ /// The length, in bytes, of the buffer pointed to by the buf parameter.
+ ///
+ /// A set of options that modify the behavior of the function call beyond the options specified for the associated socket. See the
+ /// Remarks below for more details.
+ ///
+ /// An optional pointer to a buffer in a sockaddr structure that will hold the source address upon return.
+ /// An optional pointer to the size, in bytes, of the buffer pointed to by the from parameter.
+ ///
+ ///
+ /// If no error occurs, recvfrom returns the number of bytes received. If the connection has been gracefully closed, the
+ /// return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
+ ///
+ ///
+ ///
+ /// Error code
+ /// Meaning
+ ///
+ /// -
+ /// WSANOTINITIALISED
+ /// A successful WSAStartup call must occur before using this function.
+ ///
+ /// -
+ /// WSAENETDOWN
+ /// The network subsystem has failed.
+ ///
+ /// -
+ /// WSAEFAULT
+ ///
+ /// The buffer pointed to by the buf or from parameters are not in the user address space, or the fromlen parameter is too small to
+ /// accommodate the source address of the peer address.
+ ///
+ ///
+ /// -
+ /// WSAEINTR
+ /// The (blocking) call was canceled through WSACancelBlockingCall.
+ ///
+ /// -
+ /// WSAEINPROGRESS
+ /// A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
+ ///
+ /// -
+ /// WSAEINVAL
+ ///
+ /// The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with
+ /// SO_OOBINLINE enabled, or (for byte stream-style sockets only) len was zero or negative.
+ ///
+ ///
+ /// -
+ /// WSAEISCONN
+ ///
+ /// The socket is connected. This function is not permitted with a connected socket, whether the socket is connection oriented or connectionless.
+ ///
+ ///
+ /// -
+ /// WSAENETRESET
+ /// For a datagram socket, this error indicates that the time to live has expired.
+ ///
+ /// -
+ /// WSAENOTSOCK
+ /// The descriptor in the s parameter is not a socket.
+ ///
+ /// -
+ /// WSAEOPNOTSUPP
+ ///
+ /// MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the
+ /// communication domain associated with this socket, or the socket is unidirectional and supports only send operations.
+ ///
+ ///
+ /// -
+ /// WSAESHUTDOWN
+ ///
+ /// The socket has been shut down; it is not possible to recvfrom on a socket after shutdown has been invoked with how set to
+ /// SD_RECEIVE or SD_BOTH.
+ ///
+ ///
+ /// -
+ /// WSAEWOULDBLOCK
+ /// The socket is marked as nonblocking and the recvfrom operation would block.
+ ///
+ /// -
+ /// WSAEMSGSIZE
+ /// The message was too large to fit into the buffer pointed to by the buf parameter and was truncated.
+ ///
+ /// -
+ /// WSAETIMEDOUT
+ ///
+ /// The connection has been dropped, because of a network failure or because the system on the other end went down without notice.
+ ///
+ ///
+ /// -
+ /// WSAECONNRESET
+ ///
+ /// The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket; it
+ /// is no longer usable. On a UDP-datagram socket this error indicates a previous send operation resulted in an ICMP Port
+ /// Unreachable message.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The recvfrom function reads incoming data on both connected and unconnected sockets and captures the address from which
+ /// the data was sent. This function is typically used with connectionless sockets. The local address of the socket must be known.
+ /// For server applications, this is usually done explicitly through bind. Explicit binding is discouraged for client applications.
+ /// For client applications using this function, the socket can become bound implicitly to a local address through sendto,
+ /// WSASendTo, or WSAJoinLeaf.
+ ///
+ ///
+ /// For stream-oriented sockets such as those of type SOCK_STREAM, a call to recvfrom returns as much information as is
+ /// currently available—up to the size of the buffer specified. If the socket has been configured for inline reception of OOB data
+ /// (socket option SO_OOBINLINE) and OOB data is yet unread, only OOB data will be returned. The application can use the ioctlsocket
+ /// or WSAIoctl SIOCATMARK command to determine whether any more OOB data remains to be read. The from and fromlen parameters
+ /// are ignored for connection-oriented sockets.
+ ///
+ ///
+ /// For message-oriented sockets, data is extracted from the first enqueued message, up to the size of the buffer specified. If the
+ /// datagram or message is larger than the buffer specified, the buffer is filled with the first part of the datagram, and
+ /// recvfrom generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost. For UDP if
+ /// the packet received contains no data (empty), the return value from the recvfrom function function is zero.
+ ///
+ ///
+ /// If the from parameter is nonzero and the socket is not connection oriented, (type SOCK_DGRAM for example), the network address
+ /// of the peer that sent the data is copied to the corresponding sockaddr structure. The value pointed to by fromlen is initialized
+ /// to the size of this structure and is modified, on return, to indicate the actual size of the address stored in the
+ /// sockaddr structure.
+ ///
+ ///
+ /// If no incoming data is available at the socket, the recvfrom function blocks and waits for data to arrive according to
+ /// the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value
+ /// of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect can be used
+ /// to determine when more data arrives.
+ ///
+ ///
+ /// If the socket is connection oriented and the remote side has shut down the connection gracefully, the call to recvfrom
+ /// will complete immediately with zero bytes received. If the connection has been reset recvfrom will fail with the error WSAECONNRESET.
+ ///
+ ///
+ /// The flags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
+ /// associated socket. The semantics of this function are determined by the socket options and the flags parameter. The latter is
+ /// constructed by using the bitwise OR operator with any of the following values.
+ ///
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// MSG_PEEK
+ ///
+ /// Peeks at the incoming data. The data is copied into the buffer but is not removed from the input queue. The function
+ /// subsequently returns the amount of data that can be read in a single call to the recvfrom (or recv) function, which may not be
+ /// the same as the total amount of data queued on the socket. The amount of data that can actually be read in a single call to the
+ /// recvfrom (or recv) function is limited to the data size written in the send or sendto function call.
+ ///
+ ///
+ /// -
+ /// MSG_OOB
+ /// Processes Out Of Band (OOB) data.
+ ///
+ ///
+ ///
+ /// Note When issuing a blocking Winsock call such as recvfrom, Winsock may need to wait for a network event before
+ /// the call can complete. Winsock performs an alertable wait in this situation, which can be interrupted by an asynchronous
+ /// procedure call (APC) scheduled on the same thread. Issuing another blocking Winsock call inside an APC that interrupted an
+ /// ongoing blocking Winsock call on the same thread will lead to undefined behavior, and must never be attempted by Winsock clients.
+ ///
+ /// Example Code
+ /// The following example demonstrates the use of the recvfrom function.
+ /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later.
+ ///
+ /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows
+ /// Server 2012 R2, and later.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recvfrom int recvfrom( SOCKET s, char *buf, int len, int
+ // flags, sockaddr *from, int *fromlen );
+ [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("winsock.h", MSDNShortId = "3e4282e0-3ed0-43e7-9b27-72ec36b9cfa1")]
+ public static extern int recvfrom(SOCKET s, byte[] buf, int len, int flags, SOCKADDR from, ref int fromlen);
///
/// The select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O.
@@ -3559,7 +3942,203 @@ namespace Vanara.PInvoke
// int flags );
[DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "902bb9cf-d847-43fc-8282-394d619b8f1b")]
- public static extern WSRESULT send(SOCKET s, IntPtr buf, int len, int flags);
+ public static extern int send(SOCKET s, IntPtr buf, int len, int flags);
+
+ /// The send function sends data on a connected socket.
+ /// A descriptor identifying a connected socket.
+ /// A pointer to a buffer containing the data to be transmitted.
+ /// The length, in bytes, of the data in buffer pointed to by the buf parameter.
+ ///
+ ///
+ /// A set of flags that specify the way in which the call is made. This parameter is constructed by using the bitwise OR operator
+ /// with any of the following values.
+ ///
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// MSG_DONTROUTE
+ ///
+ /// Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.
+ ///
+ ///
+ /// -
+ /// MSG_OOB
+ /// Sends OOB data (stream-style socket such as SOCK_STREAM only.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// If no error occurs, send returns the total number of bytes sent, which can be less than the number requested to be sent
+ /// in the len parameter. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
+ ///
+ ///
+ ///
+ /// Error code
+ /// Meaning
+ ///
+ /// -
+ /// WSANOTINITIALISED
+ /// A successful WSAStartup call must occur before using this function.
+ ///
+ /// -
+ /// WSAENETDOWN
+ /// The network subsystem has failed.
+ ///
+ /// -
+ /// WSAEACCES
+ ///
+ /// The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST socket
+ /// option to enable use of the broadcast address.
+ ///
+ ///
+ /// -
+ /// WSAEINTR
+ /// A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.
+ ///
+ /// -
+ /// WSAEINPROGRESS
+ /// A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
+ ///
+ /// -
+ /// WSAEFAULT
+ /// The buf parameter is not completely contained in a valid part of the user address space.
+ ///
+ /// -
+ /// WSAENETRESET
+ /// The connection has been broken due to the keep-alive activity detecting a failure while the operation was in progress.
+ ///
+ /// -
+ /// WSAENOBUFS
+ /// No buffer space is available.
+ ///
+ /// -
+ /// WSAENOTCONN
+ /// The socket is not connected.
+ ///
+ /// -
+ /// WSAENOTSOCK
+ /// The descriptor is not a socket.
+ ///
+ /// -
+ /// WSAEOPNOTSUPP
+ ///
+ /// MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the
+ /// communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.
+ ///
+ ///
+ /// -
+ /// WSAESHUTDOWN
+ ///
+ /// The socket has been shut down; it is not possible to send on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
+ ///
+ ///
+ /// -
+ /// WSAEWOULDBLOCK
+ /// The socket is marked as nonblocking and the requested operation would block.
+ ///
+ /// -
+ /// WSAEMSGSIZE
+ /// The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
+ ///
+ /// -
+ /// WSAEHOSTUNREACH
+ /// The remote host cannot be reached from this host at this time.
+ ///
+ /// -
+ /// WSAEINVAL
+ ///
+ /// The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with
+ /// SO_OOBINLINE enabled.
+ ///
+ ///
+ /// -
+ /// WSAECONNABORTED
+ ///
+ /// The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no
+ /// longer usable.
+ ///
+ ///
+ /// -
+ /// WSAECONNRESET
+ ///
+ /// The virtual circuit was reset by the remote side executing a hard or abortive close. For UDP sockets, the remote host was unable
+ /// to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet. The application should close the
+ /// socket as it is no longer usable.
+ ///
+ ///
+ /// -
+ /// WSAETIMEDOUT
+ ///
+ /// The connection has been dropped, because of a network failure or because the system on the other end went down without notice.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The send function is used to write outgoing data on a connected socket.
+ ///
+ /// For message-oriented sockets (address family of AF_INET or AF_INET6, type of SOCK_DGRAM, and protocol of
+ /// IPPROTO_UDP, for example), care must be taken not to exceed the maximum packet size of the underlying provider. The
+ /// maximum message packet size for a provider can be obtained by calling getsockopt with the optname parameter set to
+ /// SO_MAX_MSG_SIZE to retrieve the value of socket option. If the data is too long to pass atomically through the underlying
+ /// protocol, the error WSAEMSGSIZE is returned, and no data is transmitted.
+ ///
+ ///
+ /// The successful completion of a send function does not indicate that the data was successfully delivered and received to
+ /// the recipient. This function only indicates the data was successfully sent.
+ ///
+ ///
+ /// If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless
+ /// the socket has been placed in nonblocking mode. On nonblocking stream oriented sockets, the number of bytes written can be
+ /// between 1 and the requested length, depending on buffer availability on both the client and server computers. The select,
+ /// WSAAsyncSelect or WSAEventSelect functions can be used to determine when it is possible to send more data.
+ ///
+ ///
+ /// Calling send with a len parameter of zero is permissible and will be treated by implementations as successful. In such
+ /// cases, send will return zero as a valid value. For message-oriented sockets, a zero-length transport datagram is sent.
+ ///
+ ///
+ /// The flags parameter can be used to influence the behavior of the function beyond the options specified for the associated
+ /// socket. The semantics of the send function are determined by any options previously set on the socket specified in the s
+ /// parameter and the flags parameter passed to the send function.
+ ///
+ ///
+ /// The order of calls made to send is also the order in which the buffers are transmitted to the transport layer.
+ /// send should not be called on the same stream-oriented socket concurrently from different threads, because some Winsock
+ /// providers may split a large send request into multiple transmissions, and this may lead to unintended data interleaving from
+ /// multiple concurrent send requests on the same stream-oriented socket.
+ ///
+ ///
+ /// Note When issuing a blocking Winsock call such as send, Winsock may need to wait for a network event before the
+ /// call can complete. Winsock performs an alertable wait in this situation, which can be interrupted by an asynchronous procedure
+ /// call (APC) scheduled on the same thread. Issuing another blocking Winsock call inside an APC that interrupted an ongoing
+ /// blocking Winsock call on the same thread will lead to undefined behavior, and must never be attempted by Winsock clients.
+ ///
+ /// Example Code
+ /// The following example demonstrates the use of the send function.
+ /// Example Code
+ /// For a another example that uses the send function, see Getting Started With Winsock.
+ /// Notes for IrDA Sockets
+ ///
+ /// -
+ /// The Af_irda.h header file must be explicitly included.
+ ///
+ ///
+ /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later.
+ ///
+ /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows
+ /// Server 2012 R2, and later.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send int WSAAPI send( SOCKET s, const char *buf, int len,
+ // int flags );
+ [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("winsock2.h", MSDNShortId = "902bb9cf-d847-43fc-8282-394d619b8f1b")]
+ public static extern int send(SOCKET s, byte[] buf, int len, int flags);
/// The sendto function sends data to a specific destination.
/// A descriptor identifying a (possibly connected) socket.
@@ -3792,7 +4371,240 @@ namespace Vanara.PInvoke
// flags, const sockaddr *to, int tolen );
[DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "a1c89c6b-d11d-4d3e-a664-af2beed0cd09")]
- public static extern WSRESULT sendto(SOCKET s, IntPtr buf, int len, int flags, SOCKADDR to, int tolen);
+ public static extern int sendto(SOCKET s, IntPtr buf, int len, int flags, SOCKADDR to, int tolen);
+
+ /// The sendto function sends data to a specific destination.
+ /// A descriptor identifying a (possibly connected) socket.
+ /// A pointer to a buffer containing the data to be transmitted.
+ /// The length, in bytes, of the data pointed to by the buf parameter.
+ /// A set of flags that specify the way in which the call is made.
+ /// An optional pointer to a sockaddr structure that contains the address of the target socket.
+ /// The size, in bytes, of the address pointed to by the to parameter.
+ ///
+ ///
+ /// If no error occurs, sendto returns the total number of bytes sent, which can be less than the number indicated by len.
+ /// Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
+ ///
+ ///
+ ///
+ /// Error code
+ /// Meaning
+ ///
+ /// -
+ /// WSANOTINITIALISED
+ /// A successful WSAStartup call must occur before using this function.
+ ///
+ /// -
+ /// WSAENETDOWN
+ /// The network subsystem has failed.
+ ///
+ /// -
+ /// WSAEACCES
+ ///
+ /// The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST
+ /// parameter to allow the use of the broadcast address.
+ ///
+ ///
+ /// -
+ /// WSAEINVAL
+ /// An unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.
+ ///
+ /// -
+ /// WSAEINTR
+ /// A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.
+ ///
+ /// -
+ /// WSAEINPROGRESS
+ /// A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
+ ///
+ /// -
+ /// WSAEFAULT
+ /// The buf or to parameters are not part of the user address space, or the tolen parameter is too small.
+ ///
+ /// -
+ /// WSAENETRESET
+ /// The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress.
+ ///
+ /// -
+ /// WSAENOBUFS
+ /// No buffer space is available.
+ ///
+ /// -
+ /// WSAENOTCONN
+ /// The socket is not connected (connection-oriented sockets only).
+ ///
+ /// -
+ /// WSAENOTSOCK
+ /// The descriptor is not a socket.
+ ///
+ /// -
+ /// WSAEOPNOTSUPP
+ ///
+ /// MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the
+ /// communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.
+ ///
+ ///
+ /// -
+ /// WSAESHUTDOWN
+ ///
+ /// The socket has been shut down; it is not possible to sendto on a socket after shutdown has been invoked with how set to SD_SEND
+ /// or SD_BOTH.
+ ///
+ ///
+ /// -
+ /// WSAEWOULDBLOCK
+ /// The socket is marked as nonblocking and the requested operation would block.
+ ///
+ /// -
+ /// WSAEMSGSIZE
+ /// The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
+ ///
+ /// -
+ /// WSAEHOSTUNREACH
+ /// The remote host cannot be reached from this host at this time.
+ ///
+ /// -
+ /// WSAECONNABORTED
+ ///
+ /// The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no
+ /// longer usable.
+ ///
+ ///
+ /// -
+ /// WSAECONNRESET
+ ///
+ /// The virtual circuit was reset by the remote side executing a hard or abortive close. For UPD sockets, the remote host was unable
+ /// to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet. The application should close the
+ /// socket as it is no longer usable.
+ ///
+ ///
+ /// -
+ /// WSAEADDRNOTAVAIL
+ /// The remote address is not a valid address, for example, ADDR_ANY.
+ ///
+ /// -
+ /// WSAEAFNOSUPPORT
+ /// Addresses in the specified family cannot be used with this socket.
+ ///
+ /// -
+ /// WSAEDESTADDRREQ
+ /// A destination address is required.
+ ///
+ /// -
+ /// WSAENETUNREACH
+ /// The network cannot be reached from this host at this time.
+ ///
+ /// -
+ /// WSAEHOSTUNREACH
+ /// A socket operation was attempted to an unreachable host.
+ ///
+ /// -
+ /// WSAETIMEDOUT
+ ///
+ /// The connection has been dropped, because of a network failure or because the system on the other end went down without notice.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The sendto function is used to write outgoing data on a socket. For message-oriented sockets, care must be taken not to
+ /// exceed the maximum packet size of the underlying subnets, which can be obtained by using getsockopt to retrieve the value of
+ /// socket option SO_MAX_MSG_SIZE. If the data is too long to pass atomically through the underlying protocol, the error WSAEMSGSIZE
+ /// is returned and no data is transmitted.
+ ///
+ ///
+ /// The to parameter can be any valid address in the socket's address family, including a broadcast or any multicast address. To
+ /// send to a broadcast address, an application must have used setsockopt with SO_BROADCAST enabled. Otherwise, sendto will
+ /// fail with the error code WSAEACCES. For TCP/IP, an application can send to any multicast address (without becoming a group member).
+ ///
+ ///
+ /// Note If a socket is opened, a setsockopt call is made, and then a sendto call is made, Windows Sockets performs an
+ /// implicit bind function call.
+ ///
+ ///
+ /// If the socket is unbound, unique values are assigned to the local association by the system, and the socket is then marked as
+ /// bound. If the socket is connected, the getsockname function can be used to determine the local IP address and port associated
+ /// with the socket.
+ ///
+ ///
+ /// If the socket is not connected, the getsockname function can be used to determine the local port number associated with the
+ /// socket but the IP address returned is set to the wildcard address for the given protocol (for example, INADDR_ANY or "0.0.0.0"
+ /// for IPv4 and IN6ADDR_ANY_INIT or "::" for IPv6).
+ ///
+ /// The successful completion of a sendto does not indicate that the data was successfully delivered.
+ ///
+ /// The sendto function is normally used on a connectionless socket to send a datagram to a specific peer socket identified
+ /// by the to parameter. Even if the connectionless socket has been previously connected to a specific address, the to parameter
+ /// overrides the destination address for that particular datagram only. On a connection-oriented socket, the to and tolen
+ /// parameters are ignored, making sendto equivalent to send.
+ ///
+ ///
+ /// Note When issuing a blocking Winsock call such as sendto, Winsock may need to wait for a network event before the
+ /// call can complete. Winsock performs an alertable wait in this situation, which can be interrupted by an asynchronous procedure
+ /// call (APC) scheduled on the same thread. Issuing another blocking Winsock call inside an APC that interrupted an ongoing
+ /// blocking Winsock call on the same thread will lead to undefined behavior, and must never be attempted by Winsock clients.
+ ///
+ /// Example Code
+ /// The following example demonstrates the use of the sendto function.
+ /// For Sockets Using IP (Version 4)
+ ///
+ /// To send a broadcast (on a SOCK_DGRAM only), the address pointed to by the to parameter can be constructed to contain the special
+ /// IPv4 address INADDR_BROADCAST (defined in Winsock2.h), together with the intended port number. If the address pointed to by the
+ /// to parameter contains the INADDR_BROADCAST address and intended port, then the broadcast will be sent out on all interfaces to
+ /// that port.
+ ///
+ ///
+ /// If the broadcast should be sent out only on a specific interface, then the address pointed to by the to parameter should contain
+ /// the subnet broadcast address for the interface and the intended port. For example, an IPv4 network address of 192.168.1.0 with a
+ /// subnet mask of 255.255.255.0 would use a subnet broadcast address of 192.168.1.255.
+ ///
+ ///
+ /// It is generally inadvisable for a broadcast datagram to exceed the size at which fragmentation can occur, which implies that the
+ /// data portion of the datagram (excluding headers) should not exceed 512 bytes.
+ ///
+ ///
+ /// If no buffer space is available within the transport system to hold the data to be transmitted, sendto will block unless
+ /// the socket has been placed in a nonblocking mode. On nonblocking, stream oriented sockets, the number of bytes written can be
+ /// between 1 and the requested length, depending on buffer availability on both the client and server systems. The select,
+ /// WSAAsyncSelect or WSAEventSelect function can be used to determine when it is possible to send more data.
+ ///
+ ///
+ /// Calling sendto with a len of zero is permissible and will return zero as a valid value. For message-oriented sockets, a
+ /// zero-length transport datagram is sent.
+ ///
+ ///
+ /// The flags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
+ /// associated socket. The semantics of this function are determined by the socket options and the flags parameter. The latter is
+ /// constructed by using the bitwise OR operator with any of the following values.
+ ///
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// MSG_DONTROUTE
+ ///
+ /// Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.
+ ///
+ ///
+ /// -
+ /// MSG_OOB
+ /// Sends OOB data (stream-style socket such as SOCK_STREAM only).
+ ///
+ ///
+ /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later.
+ ///
+ /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows
+ /// Server 2012 R2, and later.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-sendto int sendto( SOCKET s, const char *buf, int len, int
+ // flags, const sockaddr *to, int tolen );
+ [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
+ [PInvokeData("winsock.h", MSDNShortId = "a1c89c6b-d11d-4d3e-a664-af2beed0cd09")]
+ public static extern int sendto(SOCKET s, byte[] buf, int len, int flags, SOCKADDR to, int tolen);
/// The setsockopt function sets a socket option.
/// A descriptor that identifies a socket.
@@ -5440,7 +6252,7 @@ namespace Vanara.PInvoke
// protocol );
[DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "6bf6e6c4-6268-479c-86a6-52e90cf317db")]
- public static extern SafeSOCKET socket(ADDRESS_FAMILY af, SOCK type, uint protocol);
+ public static extern SafeSOCKET socket(ADDRESS_FAMILY af, SOCK type, uint protocol = 0U);
///
/// The protoent structure contains the name and protocol numbers that correspond to a given protocol name. Applications must
diff --git a/PInvoke/Ws2_32/ws2def.cs b/PInvoke/Ws2_32/ws2def.cs
index 15825f88..74ecd4d4 100644
--- a/PInvoke/Ws2_32/ws2def.cs
+++ b/PInvoke/Ws2_32/ws2def.cs
@@ -2057,6 +2057,38 @@ namespace Vanara.PInvoke
[PInvokeData("ws2def.h", MSDNShortId = "fb6447b4-28f5-4ab7-bbdc-5a57ed38a994")]
public static class WinSockIOControlCode
{
+ ///
+ /// Determine the amount of data that can be read atomically from socket s. The lpvOutBuffer parameter points at an unsigned long
+ /// in which WSAIoctl stores the result.
+ ///
+ /// If the socket passed in the s parameter is stream oriented(for example, type SOCK_STREAM), FIONREAD returns the total amount
+ /// of data that can be read in a single receive operation; this is normally the same as the total amount of data queued on the
+ /// socket(since a data stream is byte-oriented, this is not guaranteed).
+ ///
+ ///
+ /// If the socket passed in the s parameter is message oriented(for example, type SOCK_DGRAM), FIONREAD returns the reports the
+ /// total number of bytes available to read, not the size of the first datagram(message) queued on the socket.
+ ///
+ ///
+ public static readonly uint FIONREAD = _IOR('f', 127); /* get # bytes to read */
+
+ ///
+ /// Enable or disable non-blocking mode on socket s. The lpvInBuffer parameter points at an unsigned long (QoS), which is nonzero
+ /// if non-blocking mode is to be enabled and zero if it is to be disabled. When a socket is created, it operates in blocking
+ /// mode (that is, non-blocking mode is disabled). This is consistent with BSD sockets.
+ ///
+ /// The WSAAsyncSelect or WSAEventSelect routine automatically sets a socket to non-blocking mode.If WSAAsyncSelect or
+ /// WSAEventSelect has been issued on a socket, then any attempt to use WSAIoctl to set the socket back to blocking mode will
+ /// fail with WSAEINVAL. To set the socket back to blocking mode, an application must first disable WSAAsyncSelect by calling
+ /// WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect by calling WSAEventSelect with the
+ /// lNetworkEvents parameter equal to zero.
+ ///
+ ///
+ public static readonly uint FIONBIO = _IOW('f', 126); /* set/clear non-blocking i/o */
+
+ /// Enable notification for when data is waiting to be received.
+ public static readonly uint FIOASYNC = _IOW('f', 125); /* set/clear async i/o */
+
/// Requests notification of changes in information reported through SIO_ADDRESS_LIST_QUERY
public static readonly uint SIO_ADDRESS_LIST_CHANGE = _WSAIO(IOC_WS2, 23);
@@ -2140,12 +2172,46 @@ namespace Vanara.PInvoke
[CorrespondingType(typeof(int), CorrespondingAction.Set)]
public static readonly uint SIO_TRANSLATE_HANDLE = _WSAIORW(IOC_WS2, 13);
+ /// set high watermark
+ public static readonly uint SIOCSHIWAT = _IOW('s', 0); /* set high watermark */
+
+ /// get high watermark
+ public static readonly uint SIOCGHIWAT = _IOR('s', 1); /* get high watermark */
+
+ /// set low watermark
+ public static readonly uint SIOCSLOWAT = _IOW('s', 2); /* set low watermark */
+
+ /// get low watermark
+ public static readonly uint SIOCGLOWAT = _IOR('s', 3); /* get low watermark */
+
+ ///
+ /// Determine whether or not all OOB data has been read. This applies only to a socket of stream-style (for example, type
+ /// SOCK_STREAM) that has been configured for inline reception of any OOB data (SO_OOBINLINE). If no OOB data is waiting to be
+ /// read, the operation returns TRUE. Otherwise, it returns FALSE, and the next receive operation performed on the socket will
+ /// retrieve some or all of the data preceding the mark; the application should use the SIOCATMARK operation to determine whether
+ /// any remains. If there is any normal data preceding the urgent (out of band) data, it will be received in order. (Note that
+ /// recv operations will never mix OOB and normal data in the same call.) lpvOutBuffer points at a BOOL in which WSAIoctl stores
+ /// the result.
+ ///
+ public static readonly uint SIOCATMARK = _IOR('s', 7); /* at oob mark? */
+
+ private const uint IOCPARM_MASK = 0x7f; /* parameters must be < 128 bytes */
+ private const uint IOC_VOID = 0x20000000; /* no parameters */
+ private const uint IOC_OUT = 0x40000000; /* copy out parameters */
+ private const uint IOC_IN = 0x80000000; /* copy in parameters */
+ private const uint IOC_INOUT = IOC_IN|IOC_OUT;
private const uint IOC_PROTOCOL = 0x10000000;
private const uint IOC_UNIX = 0x00000000;
private const uint IOC_VENDOR = 0x18000000;
private const uint IOC_WS2 = 0x08000000;
private const uint IOC_WSK = IOC_WS2 | 0x07000000;
+ private static uint _IO(uint x, uint y) => (IOC_VOID|((x)<<8)|(y));
+
+ private static uint _IOR(uint x, uint y) => (IOC_OUT|((sizeof(uint)&IOCPARM_MASK)<<16)|((x)<<8)|(y));
+
+ private static uint _IOW(uint x, uint y) => (IOC_IN|((sizeof(uint)&IOCPARM_MASK)<<16)|((x)<<8)|(y));
+
private static uint _WSAIO(uint x, uint y) => IOC_VOID | (x) | (y);
private static uint _WSAIOR(uint x, uint y) => IOC_OUT | (x) | (y);
diff --git a/UnitTests/PInvoke/Ws2_32/WSATests.cs b/UnitTests/PInvoke/Ws2_32/WSATests.cs
index 3613762a..2ecf5d86 100644
--- a/UnitTests/PInvoke/Ws2_32/WSATests.cs
+++ b/UnitTests/PInvoke/Ws2_32/WSATests.cs
@@ -29,7 +29,7 @@ namespace Vanara.PInvoke.Tests
var addr = new SOCKADDR(localIP4);
var len = 256U;
var sb = new StringBuilder((int)len);
- Assert.That(WSAAddressToString(addr, addr.Size, default, sb, ref len), ResultIs.Not.Value(-1));
+ Assert.That(WSAAddressToString(addr, addr.Size, default, sb, ref len), ResultIs.Successful);
TestContext.Write(sb);
Assert.That(sb.ToString(), Is.EqualTo(localIP4.ToString()));
}
@@ -48,12 +48,12 @@ namespace Vanara.PInvoke.Tests
public void WSAEnumNameSpaceProvidersTest()
{
var len = 0U;
- Assert.That(WSAEnumNameSpaceProviders(ref len, default), ResultIs.Value(-1));
+ Assert.That(WSAEnumNameSpaceProviders(ref len, default), ResultIs.Failure);
//Assert.That(WSAGetLastError(), Is.EqualTo((Win32Error)Win32Error.WSAEFAULT));
Assert.That(len, Is.GreaterThan(0));
using var mem = new SafeHGlobalHandle(len);
var cnt = WSAEnumNameSpaceProviders(ref len, mem);
- Assert.That(cnt, ResultIs.Not.Value(-1));
+ Assert.That(cnt, ResultIs.Successful);
TestContext.Write(string.Join("\n", mem.ToEnumerable(cnt).Select(n => $"{n.lpszIdentifier.ToString()}: {n.NSProviderId}, {n.dwNameSpace}, {n.fActive}")));
}
@@ -61,12 +61,12 @@ namespace Vanara.PInvoke.Tests
public void WSAEnumNameSpaceProvidersExTest()
{
var len = 0U;
- Assert.That(WSAEnumNameSpaceProvidersEx(ref len, default), ResultIs.Value(-1));
+ Assert.That(WSAEnumNameSpaceProvidersEx(ref len, default), ResultIs.Failure);
//Assert.That(WSAGetLastError(), Is.EqualTo((Win32Error)Win32Error.WSAEFAULT));
Assert.That(len, Is.GreaterThan(0));
using var mem = new SafeHGlobalHandle(len);
var cnt = WSAEnumNameSpaceProvidersEx(ref len, mem);
- Assert.That(cnt, ResultIs.Not.Value(-1));
+ Assert.That(cnt, ResultIs.Successful);
TestContext.Write(string.Join("\n", mem.ToEnumerable(cnt).Select(n => $"{n.lpszIdentifier.ToString()}: {n.NSProviderId}, {n.dwNameSpace}, {n.fActive}")));
}
@@ -75,32 +75,32 @@ namespace Vanara.PInvoke.Tests
{
var ListenSocket = tcpSocket;
var InetAddr = new SOCKADDR(IN_ADDR.INADDR_ANY, htons(27015));
- Assert.That(bind(ListenSocket, InetAddr, InetAddr.Size), ResultIs.Not.Value(-1));
+ Assert.That(bind(ListenSocket, InetAddr, InetAddr.Size), ResultIs.Successful);
using var evt = WSACreateEvent();
Assert.That(evt, ResultIs.ValidHandle);
- Assert.That(WSAEventSelect(ListenSocket, evt, FD.FD_ACCEPT | FD.FD_CLOSE), ResultIs.Not.Value(-1));
- Assert.That(listen(ListenSocket, 10), ResultIs.Not.Value(-1));
+ Assert.That(WSAEventSelect(ListenSocket, evt, FD.FD_ACCEPT | FD.FD_CLOSE), ResultIs.Successful);
+ Assert.That(listen(ListenSocket, 10), ResultIs.Successful);
var EventArray = new WSAEVENT[] { evt };
WSAWaitForMultipleEvents((uint)EventArray.Length, EventArray, true, 500, false);
- Assert.That(WSAEnumNetworkEvents(ListenSocket, evt, out var nets), ResultIs.Not.Value(-1));
+ Assert.That(WSAEnumNetworkEvents(ListenSocket, evt, out var nets), ResultIs.Successful);
}
[Test]
public void WSAEnumProtocolsTest()
{
var len = 0U;
- Assert.That(WSAEnumProtocols(null, default, ref len), ResultIs.Value(-1));
+ Assert.That(WSAEnumProtocols(null, default, ref len), ResultIs.Failure);
Assert.That(len, Is.GreaterThan(0));
using var mem = new SafeHGlobalHandle(len);
var cnt = WSAEnumProtocols(null, mem, ref len);
- Assert.That(cnt, ResultIs.Not.Value(-1));
+ Assert.That(cnt, ResultIs.Successful);
TestContext.Write(string.Join("\n", mem.ToEnumerable(cnt).Select(p => $"{p.szProtocol}: {(ADDRESS_FAMILY)p.iAddressFamily}, {p.iSocketType}, {p.iProtocol}")));
}
[Test]
public void WSAHtonlTest()
{
- Assert.That(WSAHtonl(tcpSocket, 0x01020304, out var ret), ResultIs.Not.Value(-1));
+ Assert.That(WSAHtonl(tcpSocket, 0x01020304, out var ret), ResultIs.Successful);
Assert.That(ret, Is.EqualTo(0x04030201));
}
}
diff --git a/UnitTests/PInvoke/Ws2_32/Ws2tcpipTests.cs b/UnitTests/PInvoke/Ws2_32/Ws2tcpipTests.cs
index 0447421b..924e5908 100644
--- a/UnitTests/PInvoke/Ws2_32/Ws2tcpipTests.cs
+++ b/UnitTests/PInvoke/Ws2_32/Ws2tcpipTests.cs
@@ -30,7 +30,7 @@ namespace Vanara.PInvoke.Tests
[Test]
public void gai_strerrorTest()
{
- Assert.That(gai_strerror((int)Win32Error.WSAEINVAL), Is.Not.Null);
+ Assert.That(gai_strerror(WSRESULT.WSAEINVAL), Is.Not.Null);
}
[Test]