Partager via


WSAConnectByNameA, fonction (winsock2.h)

La fonction WSAConnectByName établit une connexion à un hôte et un port spécifiés. Cette fonction est fournie pour permettre une connexion rapide à un point de terminaison réseau en fonction d’un nom d’hôte et d’un port.

Cette fonction prend en charge les adresses IPv4 et IPv6.

Syntaxe

BOOL WSAConnectByNameA(
  [in]      SOCKET          s,
  [in]      LPCSTR          nodename,
  [in]      LPCSTR          servicename,
  [in, out] LPDWORD         LocalAddressLength,
  [out]     LPSOCKADDR      LocalAddress,
  [in, out] LPDWORD         RemoteAddressLength,
  [out]     LPSOCKADDR      RemoteAddress,
  [in]      const timeval   *timeout,
            LPWSAOVERLAPPED Reserved
);

Paramètres

[in] s

Descripteur qui identifie un socket non connecté.

Note Sur Windows 7, Windows Server 2008 R2 et versions antérieures, la fonction WSAConnectByName nécessite un socket indépendant et non connecté. Cela diffère des autres appels Winsock pour établir une connexion (par exemple, WSAConnect).
 

[in] nodename

Chaîne terminée par null qui contient le nom de l’hôte ou l’adresse IP de l’hôte sur lequel se connecter pour IPv4 ou IPv6.

[in] servicename

Chaîne terminée par null qui contient le nom de service ou le port de destination de l’hôte sur lequel se connecter pour IPv4 ou IPv6.

Un nom de service est un alias de chaîne pour un numéro de port. Par exemple, « http » est un alias pour le port 80 défini par l’Internet Engineering Task Force (IETF) comme port par défaut utilisé par les serveurs web pour le protocole HTTP. Les valeurs possibles pour le paramètre servicename quand aucun numéro de port n’est spécifié sont répertoriées dans le fichier suivant :

%WINDIR%\system32\drivers\etc\services

[in, out] LocalAddressLength

Lors de l’entrée, pointeur vers la taille, en octets, de la mémoire tampon LocalAddress fournie par l’appelant. Lors de la sortie, pointeur vers la taille, en octets, du SOCKADDR pour l’adresse locale stockée dans la mémoire tampon LocalAddress renseignée par le système à l’issue de l’appel.

[out] LocalAddress

Pointeur vers la structure SOCKADDR qui reçoit l’adresse locale de la connexion. La taille du paramètre est exactement la taille retournée dans LocalAddressLength. Il s’agit des mêmes informations que celles qui seraient retournées par la fonction getsockname . Ce paramètre peut être NULL, auquel cas, le paramètre LocalAddressLength est ignoré.

[in, out] RemoteAddressLength

Lors de l’entrée, pointeur vers la taille, en octets, de la mémoire tampon RemoteAddress fournie par l’appelant. Lors de la sortie, pointeur vers la taille, en octets, du SOCKADDR pour l’adresse distante stockée dans la mémoire tampon RemoteAddress renseignée par le système à l’issue de l’appel.

[out] RemoteAddress

Pointeur vers la structure SOCKADDR qui reçoit l’adresse distante de la connexion. Il s’agit des mêmes informations que celles qui seraient retournées par la fonction getpeername . Ce paramètre peut être NULL, auquel cas l’élément RemoteAddressLength est ignoré.

[in] timeout

Temps, en millisecondes, d’attente d’une réponse de l’application distante avant d’arrêter l’appel.

Reserved

Réservé pour une implémentation ultérieure. Ce paramètre doit être défini sur NULL.

Valeur retournée

Si une connexion est établie, WSAConnectByName retourne TRUE et les paramètres LocalAddress et RemoteAddress sont renseignés si ces mémoires tampons ont été fournies par l’appelant.

Si l’appel échoue, FALSE est retourné. WSAGetLastError peut ensuite être appelé pour obtenir des informations d’erreur étendues.

Code de retour Description
WSAEHOSTUNREACH
L’hôte passé en tant que paramètre nodename était inaccessible.
WSAEINVAL
Un paramètre non valide a été transmis à la fonction. Le paramètre nodename ou servicename ne doit pas être NULL. Le paramètre Reserved doit être NULL.
WSAENOBUFS
La mémoire insuffisante n’a pas pu être allouée.
WSAENOTSOCK
Un socket non valide a été passé à la fonction . Le paramètre s ne doit pas être INVALID_SOCKET ou NULL.
WSAETIMEDOUT
Aucune réponse de l’application distante n’a été reçue avant le dépassement du paramètre de délai d’expiration .

Remarques

WSAConnectByName est fourni pour permettre des connexions rapides et transparentes aux hôtes distants sur des ports spécifiques. Il est compatible avec les versions IPv6 et IPv4.

Pour activer les communications IPv6 et IPv4, utilisez la méthode suivante :

  • La fonction setsockopt doit être appelée sur un socket créé pour la famille d’adresses AF_INET6 afin de désactiver l’option de socket IPV6_V6ONLY avant d’appeler WSAConnectByName. Pour ce faire, appelez la fonction setsockopt sur le socket avec le paramètre de niveau défini sur IPPROTO_IPV6 (voir options de socket IPPROTO_IPV6), le paramètre optname défini sur IPV6_V6ONLY et la valeur du paramètre optvalue définie sur zéro .

WSAConnectByName présente des limitations : il fonctionne uniquement pour les sockets orientés connexion, tels que ceux de type SOCK_STREAM. La fonction ne prend pas en charge le comportement d’E/S qui se chevauche ou qui ne bloque pas. WSAConnectByName se bloque même si le socket est en mode non bloquant.

WSAConnectByName ne prend pas en charge les données fournies par l’utilisateur lors de l’établissement d’une connexion. Cet appel ne prend pas non plus en charge les structures FLOWSPEC. Dans les cas où ces fonctionnalités sont requises, WSAConnect doit être utilisé à la place.

Dans les versions antérieures à Windows 10, si une application doit être liée à une adresse ou à un port local spécifique, WSAConnectByName ne peut pas être utilisé, car le paramètre socket pour WSAConnectByName doit être un socket indépendant.

Cette restriction a été supprimée Windows 10.

Les paramètres RemoteAddress et LocalAddress pointent vers une structure SOCKADDR , qui est un type de données générique. Lorsque WSAConnectByName est appelé, il est attendu qu’un type d’adresse de socket spécifique au protocole réseau ou à la famille d’adresses utilisée soit effectivement passé dans ces paramètres. Ainsi, pour les adresses IPv4, un pointeur vers une structure sockaddr_in est converti en pointeur vers SOCKADDR en tant que paramètres RemoteAddress et LocalAddress . Pour les adresses IPv6, un pointeur vers une structure sockaddr_in6 est converti en pointeur vers SOCKADDR en tant que paramètres RemoteAddress et LocalAddress .

Lorsque la fonction WSAConnectByName retourne TRUE, les sockets sont dans l’état par défaut d’un socket connecté. Le socket s n’active pas les propriétés ou options définies précédemment tant que SO_UPDATE_CONNECT_CONTEXT n’est pas défini sur le socket. Utilisez la fonction setsockopt pour définir l’option SO_UPDATE_CONNECT_CONTEXT.

Par exemple :

//Need to #include <mswsock.h> for SO_UPDATE_CONNECT_CONTEXT

int iResult = 0;

iResult = setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 );

Note Lors de l’émission d’un appel Winsock bloquant tel que WSAConnectByName avec le paramètre de délai d’expiration défini sur NULL, Winsock peut avoir besoin d’attendre un événement réseau avant que l’appel puisse se terminer. Winsock effectue une attente pouvant être alertée dans cette situation, qui peut être interrompue par un appel de procédure asynchrone (APC) planifié sur le même thread. L’émission d’un autre appel Winsock bloquant à l’intérieur d’un APC qui interrompt un appel Winsock bloquant en cours sur le même thread entraîne un comportement non défini et ne doit jamais être tenté par les clients Winsock.
 
Windows Phone 8 : la fonction WSAConnectByNameW est prise en charge pour les applications Windows Phone Store sur Windows Phone 8 et versions ultérieures.

Windows 8.1 et Windows Server 2012 R2 : la fonction WSAConnectByNameW est prise en charge pour les applications du Windows Store sur Windows 8.1, Windows Server 2012 R2 et versions ultérieures.

Exemples

Établissez une connexion à l’aide de WSAConnectByName.

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <mswsock.h>   // Need for SO_UPDATE_CONNECT_CONTEXT
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

SOCKET
OpenAndConnect(LPWSTR NodeName, LPWSTR PortName) 
{
    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){
        wprintf(L"socket failed with error: %d\n", WSAGetLastError());
        return INVALID_SOCKET;
    }

    iResult = setsockopt(ConnSocket, IPPROTO_IPV6,
        IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
    if (iResult == SOCKET_ERROR){
        wprintf(L"setsockopt for IPV6_V6ONLY failed with error: %d\n",
            WSAGetLastError());
        closesocket(ConnSocket);
        return INVALID_SOCKET;       
    }

    bSuccess = WSAConnectByName(ConnSocket, NodeName, 
            PortName, &dwLocalAddr,
            (SOCKADDR*)&LocalAddr,
            &dwRemoteAddr,
            (SOCKADDR*)&RemoteAddr,
            NULL,
            NULL);
    if (!bSuccess){
        wprintf(L"WsaConnectByName failed with error: %d\n", WSAGetLastError());
        closesocket(ConnSocket);
        return INVALID_SOCKET;       

    
    }

    iResult = setsockopt(ConnSocket, SOL_SOCKET,
        SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
    if (iResult == SOCKET_ERROR){
        wprintf(L"setsockopt for SO_UPDATE_CONNECT_CONTEXT failed with error: %d\n",
            WSAGetLastError());
        closesocket(ConnSocket);
        return INVALID_SOCKET;       
    }

    return ConnSocket;
}

int __cdecl wmain(int argc, wchar_t **argv)
{
   //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData;
    int iResult;

    SOCKET s = INVALID_SOCKET;

    // Validate the parameters
    if (argc != 3) {
        wprintf(L"usage: %ws <Nodename> <Portname>\n", argv[0]);
        wprintf(L"wsaconnectbyname establishes a connection to a specified host and port.\n");
        wprintf(L"%ws www.contoso.com 8080\n", argv[0]);
        return 1;
    }

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        wprintf(L"WSAStartup failed: %d\n", iResult);
        return 1;
    }

    wprintf(L"WsaConnectByName with following parameters:\n");
    wprintf(L"\tNodename = %ws\n", argv[1]);
    wprintf(L"\tPortname (or port) = %ws\n\n", argv[2]);

    //--------------------------------
    // Call our function that uses the WsaConnectByName. 
    
    s = OpenAndConnect(argv[1], argv[2]);
    if ( s == INVALID_SOCKET ) {
        wprintf(L"WsaConnectByName failed with error: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    else
    {
        wprintf(L"WsaConnectByName succeeded\n");
        
        closesocket(s);
        WSACleanup();
        return 0;
    }
}

Notes

L’en-tête winsock2.h définit WSAConnectByName en tant qu’alias qui sélectionne automatiquement la version ANSI ou Unicode de cette fonction en fonction de la définition de la constante de préprocesseur UNICODE. La combinaison de l’utilisation de l’alias neutre en encodage avec du code qui n’est pas neutre en encodage peut entraîner des incompatibilités qui entraînent des erreurs de compilation ou d’exécution. Pour plus d’informations, consultez Conventions pour les prototypes de fonction.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows 8.1, Windows Vista [applications de bureau | Applications UWP]
Serveur minimal pris en charge Windows Server 2008 [applications de bureau | applications UWP]
Plateforme cible Windows
En-tête winsock2.h
Bibliothèque Ws2_32.lib
DLL Ws2_32.dll

Voir aussi

IPPROTO_IPV6 Socket Options

SOCKADDR

WSAConnect

WSAConnectByList

WSAGetLastError

getaddrinfo

getpeername

getsockname

setockopt