다음을 통해 공유


WSAConnectByNameW 함수(winsock2.h)

WSAConnectByName 함수는 지정된 호스트 및 포트에 대한 연결을 설정합니다. 이 함수는 호스트 이름 및 포트가 지정된 네트워크 엔드포인트에 대한 빠른 연결을 허용하기 위해 제공됩니다.

이 함수는 IPv4 및 IPv6 주소를 모두 지원합니다.

구문

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

매개 변수

[in] s

연결되지 않은 소켓을 식별하는 설명자입니다.

참고 Windows 7, Windows Server 2008 R2 및 이전 버전에서는 WSAConnectByName 함수에 바인딩되지 않은 연결되지 않은 소켓이 필요합니다. 이는 연결을 설정하는 다른 Winsock 호출과 다릅니다(예: WSAConnect).
 

[in] nodename

IPv4 또는 IPv6에 연결할 호스트의 IP 주소 또는 호스트의 이름을 포함하는 NULL로 끝나는 문자열입니다.

[in] servicename

IPv4 또는 IPv6에 연결할 호스트의 서비스 이름 또는 대상 포트를 포함하는 NULL로 끝나는 문자열입니다.

서비스 이름은 포트 번호의 문자열 별칭입니다. 예를 들어 "http"는 IETF(인터넷 엔지니어링 태스크 포스)에서 HTTP 프로토콜에 대해 웹 서버에서 사용하는 기본 포트로 정의된 포트 80의 별칭입니다. 포트 번호를 지정하지 않은 경우 servicename 매개 변수에 사용할 수 있는 값은 다음 파일에 나열됩니다.

%WINDIR%\system32\drivers\etc\services

[in, out] LocalAddressLength

입력 시 호출자가 제공하는 LocalAddress 버퍼의 크기(바이트)에 대한 포인터입니다. 출력 시 호출이 성공적으로 완료되면 시스템에서 입력한 LocalAddress 버퍼에 저장된 로컬 주소에 대한 SOCKADDR의 크기(바이트)에 대한 포인터입니다.

[out] LocalAddress

연결의 로컬 주소를 수신하는 SOCKADDR 구조체에 대한 포인터입니다. 매개 변수의 크기는 LocalAddressLength에서 반환된 크기입니다. 이 정보는 getsockname 함수에서 반환되는 것과 동일한 정보입니다. 이 매개 변수는 NULL일 수 있으며, 이 경우 LocalAddressLength 매개 변수는 무시됩니다.

[in, out] RemoteAddressLength

입력 시 호출자가 제공하는 RemoteAddress 버퍼의 크기(바이트)에 대한 포인터입니다. 출력 시 호출이 성공적으로 완료되면 시스템에서 RemoteAddress 버퍼에 저장된 원격 주소에 대한 SOCKADDR 크기(바이트)에 대한 포인터입니다.

[out] RemoteAddress

연결의 원격 주소를 수신하는 SOCKADDR 구조체에 대한 포인터입니다. getpeername 함수에서 반환하는 것과 동일한 정보입니다. 이 매개 변수는 NULL일 수 있으며, 이 경우 RemoteAddressLength 는 무시됩니다.

[in] timeout

호출을 중단하기 전에 원격 애플리케이션의 응답을 기다리는 시간(밀리초)입니다.

Reserved

향후 구현을 위해 예약됩니다. 이 매개 변수는 NULL로 설정해야 합니다.

반환 값

연결이 설정되면 WSAConnectByNameTRUE 를 반환하고, 호출자가 이러한 버퍼를 제공한 경우 LocalAddressRemoteAddress 매개 변수가 채워집니다.

호출이 실패하면 FALSE 가 반환됩니다. 그런 다음 WSAGetLastError를 호출하여 확장된 오류 정보를 가져올 수 있습니다.

반환 코드 설명
WSAEHOSTUNREACH
nodename 매개 변수로 전달된 호스트에 연결할 수 없습니다.
WSAEINVAL
잘못된 매개 변수가 함수에 전달되었습니다. nodename 또는 servicename 매개 변수는 NULL이 아니어야 합니다. Reserved 매개 변수는 NULL이어야 합니다.
WSAENOBUFS
충분한 메모리를 할당할 수 없습니다.
WSAENOTSOCK
잘못된 소켓이 함수에 전달되었습니다. s 매개 변수는 INVALID_SOCKET 또는 NULL이 아니어야 합니다.
WSAETIMEDOUT
시간 제한 매개 변수를 초과하기 전에 원격 애플리케이션의 응답을 받지 못했습니다.

설명

WSAConnectByName 은 특정 포트의 원격 호스트에 빠르고 투명한 연결을 사용하도록 설정하기 위해 제공됩니다. IPv6 및 IPv4 버전 모두와 호환됩니다.

IPv6 및 IPv4 통신을 모두 사용하도록 설정하려면 다음 방법을 사용합니다.

  • WSAConnectByName을 호출하기 전에 IPV6_V6ONLY 소켓 옵션을 사용하지 않도록 설정하려면 AF_INET6 주소 패밀리에 대해 만든 소켓에서 setsockopt 함수를 호출해야 합니다. 이 작업은 수준 매개 변수가 IPPROTO_IPV6(IPPROTO_IPV6 Socket 옵션 참조), optname 매개 변수가 IPV6_V6ONLY 설정되고 optvalue 매개 변수 값이 0으로 설정된 소켓에서 setsockopt 함수를 호출하여 수행됩니다.

WSAConnectByName 에는 제한 사항이 있습니다. SOCK_STREAM 형식의 소켓과 같은 연결 지향 소켓에만 작동합니다. 함수는 겹치는 I/O 또는 비블로킹 동작을 지원하지 않습니다. 소켓이 비차단 모드인 경우에도 WSAConnectByName이 차단됩니다.

WSAConnectByName 은 연결을 만드는 동안 사용자가 제공한 데이터를 지원하지 않습니다. 이 호출은 FLOWSPEC 구조도 지원하지 않습니다. 이러한 기능이 필요한 경우 WSAConnect 를 대신 사용해야 합니다.

Windows 10 이전 버전에서 애플리케이션이 특정 로컬 주소 또는 포트에 바인딩해야 하는 경우 WSAConnectByName에 대한 소켓 매개 변수가 언바운드 소켓이어야 하므로 WSAConnectByName을 사용할 수 없습니다.

이 제한은 Windows 10 제거되었습니다.

RemoteAddressLocalAddress 매개 변수는 제네릭 데이터 형식인 SOCKADDR 구조를 가리킵니다. WSAConnectByName이 호출되면 사용 중인 네트워크 프로토콜 또는 주소 패밀리와 관련된 소켓 주소 형식이 실제로 이러한 매개 변수에 전달될 것으로 예상됩니다. 따라서 IPv4 주소의 경우 sockaddr_in 구조체에 대한 포인터는 RemoteAddressLocalAddress 매개 변수로 SOCKADDR에 대한 포인터로 캐스팅됩니다. IPv6 주소의 경우 sockaddr_in6 구조체에 대한 포인터는 RemoteAddressLocalAddress 매개 변수로 SOCKADDR에 대한 포인터로 캐스팅됩니다.

WSAConnectByName 함수가 TRUE를 반환하면 소켓 연결된 소켓의 기본 상태에 있습니다. 소켓 s 는 소켓에서 SO_UPDATE_CONNECT_CONTEXT 설정될 때까지 이전에 설정된 속성 또는 옵션을 사용하도록 설정하지 않습니다. setsockopt 함수를 사용하여 SO_UPDATE_CONNECT_CONTEXT 옵션을 설정합니다.

예를 들면 다음과 같습니다.

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

int iResult = 0;

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

참고시간 제한 매개 변수가 NULL로 설정된 WSAConnectByName과 같은 차단 Winsock 호출을 실행하는 경우 Winsock은 호출이 완료되기 전에 네트워크 이벤트를 기다려야 할 수 있습니다. Winsock은 이 상황에서 경고 가능한 대기를 수행합니다. 이 대기는 동일한 스레드에서 예약된 APC(비동기 프로시저 호출)에 의해 중단될 수 있습니다. 동일한 스레드에서 지속적인 차단 Winsock 호출을 중단한 APC 내에서 다른 차단 Winsock 호출을 실행하면 정의되지 않은 동작이 발생하며 Winsock 클라이언트에서 시도해서는 안 됩니다.
 
Windows Phone 8:WSAConnectByNameW 함수는 Windows Phone 8 이상에서 Windows Phone 스토어 앱에 대해 지원됩니다.

Windows 8.1Windows Server 2012 R2: WSAConnectByNameW 함수는 Windows 8.1, Windows Server 2012 R2 이상의 Windows 스토어 앱에서 지원됩니다.

예제

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;
    }
}

참고

winsock2.h 헤더는 WSAConnectByName을 유니코드 전처리기 상수의 정의에 따라 이 함수의 ANSI 또는 유니코드 버전을 자동으로 선택하는 별칭으로 정의합니다. 인코딩 중립 별칭을 인코딩 중립이 아닌 코드와 혼합하면 컴파일 또는 런타임 오류가 발생하는 불일치가 발생할 수 있습니다. 자세한 내용은 함수 프로토타입에 대한 규칙을 참조하세요.

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows 8.1, Windows Vista [데스크톱 앱 | UWP 앱]
지원되는 최소 서버 Windows Server 2008 [데스크톱 앱 | UWP 앱]
대상 플랫폼 Windows
헤더 winsock2.h
라이브러리 Ws2_32.lib
DLL Ws2_32.dll

추가 정보

IPPROTO_IPV6 소켓 옵션

SOCKADDR

WSAConnect

WSAConnectByList

WSAGetLastError

getaddrinfo

getpeername

getsockname

setsockopt