WSAConnectByList function (winsock2.h)
The WSAConnectByList function establishes a connection to one out of a collection of possible endpoints represented by a set of destination addresses (host names and ports). This function takes all the destination addresses passed to it and all of the local computer's source addresses, and tries connecting using all possible address combinations before giving up.
This function supports both IPv4 and IPv6 addresses.
Syntax
BOOL WSAConnectByList(
[in] SOCKET s,
[in] PSOCKET_ADDRESS_LIST SocketAddress,
[in, out] LPDWORD LocalAddressLength,
[out] LPSOCKADDR LocalAddress,
[in, out] LPDWORD RemoteAddressLength,
[out] LPSOCKADDR RemoteAddress,
[in] const timeval *timeout,
[in] LPWSAOVERLAPPED Reserved
);
Parameters
[in] s
A descriptor that identifies an unbound and unconnected socket. Note that unlike other Winsock calls to establish a connection (for example, WSAConnect), the WSAConnectByList function requires an unbound socket.
[in] SocketAddress
A pointer to a SOCKET_ADDRESS_LIST structure that represents the possible destination address and port pairs to connect to a peer. It is the application's responsibility to fill in the port number in the each SOCKET_ADDRESS structure in the SOCKET_ADDRESS_LIST.
[in, out] LocalAddressLength
On input, a pointer to the size, in bytes, of the LocalAddress buffer provided by the caller. On output, a pointer to the size, in bytes, of the SOCKADDR for the local address stored in the LocalAddress buffer filled in by the system upon successful completion of the call.
[out] LocalAddress
A pointer to the SOCKADDR structure that receives the local address of the connection. The size of the parameter is exactly the size returned in LocalAddressLength. This is the same information that would be returned by the getsockname function. This parameter can be NULL, in which case, the LocalAddressLength parameter is ignored.
[in, out] RemoteAddressLength
On input, a pointer to the size, in bytes, of the RemoteAddress buffer provided by the caller. On output, a pointer to the size, in bytes, of the SOCKADDR for the remote address stored in RemoteAddress buffer filled-in by the system upon successful completion of the call.
[out] RemoteAddress
A pointer to the SOCKADDR structure that receives the remote address of the connection. This is the same information that would be returned by the getpeername function. This parameter can be NULL, in which case, the RemoteAddressLength is ignored.
[in] timeout
The time, in milliseconds, to wait for a response from the remote application before aborting the call. This parameter can be NULL in which case WSAConnectByList will complete after either the connection is successfully established or after a connection was attempted and failed on all possible local-remote address pairs.
[in] Reserved
Reserved for future implementation. This parameter must be set to NULL.
Return value
If a connection is established, WSAConnectByList returns TRUE and LocalAddress and RemoteAddress parameters are filled in if these buffers were supplied by the caller.
If the call fails, FALSE is returned. WSAGetLastError can then be called to get extended error information.
Return code | Description |
---|---|
|
The host passed as the nodename parameter was unreachable. |
|
An invalid parameter was passed to the function. The Reserved parameter must be NULL. |
|
Sufficient memory could not be allocated. |
|
An invalid socket was passed to the function. The s parameter must not be INVALID_SOCKET or NULL. |
|
A response from the remote application was not received before the timeout parameter was exceeded. |
Remarks
WSAConnectByList is similar to the WSAConnectByName function. Instead of taking a single host name and service name (port), WSAConnectByList takes a list of addresses (host addresses and ports) and connects to one of the addresses. The WSAConnectByList function is designed to support peer-to-peer collaboration scenarios where an application needs to connect to any available node out of a list of potential nodes. WSAConnectByList is compatible with both IPv6 and IPv4 versions.
The set of possible destinations, represented by a list of addresses, is provided by the caller. WSAConnectByList does more than simply attempt to connect to one of possibly many destination addresses. Specifically, the function takes all remote addresses passed in by the caller, all local addresses, and then attempts a connection first using address pairs with the highest chance of success. As such, WSAConnectByList not only ensures that connection will be established if a connection is at all possible, but also minimizes the time to establish the connection.
The caller can specify the LocalAddress and RemoteAddress buffers and lengths to determine the local and remote addresses for which the connection was successfully established.
The timeout parameter allows the caller to limit the time spent by the function in establishing a connection. Internally, WSAConnectByList performs multiple operations (connection attempts). In between each operation, the timeout parameter is checked to see if the timeout has been exceeded and, if so, the call is aborted. Note that an individual operation (connect) will not be interrupted once the timeout is exceeded, so the WSAConnectByList call can take longer to time out than the value specified in the timeout parameter.
WSAConnectByList has limitations: It works only for connection-oriented sockets, such as those of type SOCK_STREAM. The function does not support overlapped I/O or non-blocking behavior. WSAConnectByList will block even if the socket is in non-blocking mode. WSAConnectByList will try connecting (one-by-one) to the various addresses provided by the caller. Potentially, each of these connection attempts may fail with a different error code. Since only a single error code can be returned, the value returned is the error code from the last connection attempt.
To enable both IPv6 and IPv4 addresses to be passed in the single address list accepted by the function, the following steps must be performed prior to calling the function:
- The setsockopt function must be called on a socket created for the AF_INET6 address family to disable the IPV6_V6ONLY socket option before calling WSAConnectByList. This is accomplished by calling the setsockopt function on the socket with the level parameter set to IPPROTO_IPV6 (see IPPROTO_IPV6 Socket Options), the optname parameter set to IPV6_V6ONLY, and the optvalue parameter value set to zero .
- Any IPv4 addresses must be represented in the IPv4-mapped IPv6 address format which enables an IPv6 only application to communicate with an IPv4 node. The IPv4-mapped IPv6 address format allows the IPv4 address of an IPv4 node to be represented as an IPv6 address. The IPv4 address is encoded into the low-order 32 bits of the IPv6 address, and the high-order 96 bits hold the fixed prefix 0:0:0:0:0:FFFF. The IPv4-mapped IPv6 address format is specified in RFC 4291. For more information, see www.ietf.org/rfc/rfc4291.txt. The IN6ADDR_SETV4MAPPED macro in Mstcpip.h can be used to convert an IPv4 address to the required IPv4-mapped IPv6 address format.
The arrays of pointers passed in the SocketAddressList parameter point to an array of SOCKET_ADDRESS structures, which are a generic data type. The RemoteAddress and the LocalAddress parameters also point to SOCKADDR structures. When WSAConnectByList is called, it is expected that a socket address type specific to the network protocol or address family being used will actually be passed in these parameters. So for IPv4 addresses, a pointer to a sockaddr_in structure would be cast to a pointer to SOCKADDR when passed as a parameter. For IPv6 addresses, a pointer to a sockaddr_in6 structure would be cast to a pointer to SOCKADDR when passed as a parameter. The SocketAddressList parameter can contain pointers to a mixture of IPv4 and IPv6 addresses. So some SOCKET_ADDRESS pointers can be to sockaddr_in structures and others can be to sockaddr_in6 structures. If it is expected that IPv6 addresses can be used, then the RemoteAddress and LocalAddress parameters should point to sockaddr_in6 structures and be cast to SOCKADDR structures. The RemoteAddressLength and the LocalAddressLength parameters must represent the length of these larger structures.
When the WSAConnectByList function returns TRUE, the socket s is in the default state for a connected socket. The socket s does not enable previously set properties or options until SO_UPDATE_CONNECT_CONTEXT is set on the socket. Use the setsockopt function to set the SO_UPDATE_CONNECT_CONTEXT option.
For example:
//Need to #include <mswsock.h> for SO_UPDATE_CONNECT_CONTEXT
int iResult = 0;
iResult = setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 );
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.
Examples
Establish a connection using WSAConnectByList.
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
SOCKET
OpenAndConnect(SOCKET_ADDRESS_LIST *AddressList)
{
SOCKET ConnSocket = INVALID_SOCKET;
int ipv6only = 0;
int iResult;
BOOL bSuccess;
SOCKADDR_STORAGE LocalAddr = {0};
SOCKADDR_STORAGE RemoteAddr = {0};
DWORD dwLocalAddr = sizeof(LocalAddr);
DWORD dwRemoteAddr = sizeof(RemoteAddr);
ConnSocket = socket(AF_INET6, SOCK_STREAM, 0);
if (ConnSocket == INVALID_SOCKET){
return INVALID_SOCKET;
}
iResult = setsockopt(ConnSocket, IPPROTO_IPV6,
IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
if (iResult == SOCKET_ERROR){
closesocket(ConnSocket);
return INVALID_SOCKET;
}
// AddressList may contain IPv6 and/or IPv4Mapped addresses
bSuccess = WSAConnectByList(ConnSocket,
AddressList,
&dwLocalAddr,
(SOCKADDR*)&LocalAddr,
&dwRemoteAddr,
(SOCKADDR*)&RemoteAddr,
NULL,
NULL);
if (bSuccess){
return ConnSocket;
} else {
return INVALID_SOCKET;
}
}
Requirements
Requirement | Value |
---|---|
Minimum supported client | Windows 8.1, Windows Vista [desktop apps | UWP apps] |
Minimum supported server | Windows Server 2003 [desktop apps | UWP apps] |
Target Platform | Windows |
Header | winsock2.h |
Library | Ws2_32.lib |
DLL | Ws2_32.dll |