WSAConnectByNameA 関数 (winsock2.h)

WSAConnectByName 関数は、指定されたホストとポートへの接続を確立します。 この関数は、ホスト名とポートを指定してネットワーク エンドポイントにすばやく接続できるようにするために提供されます。

この関数は、IPv4 アドレスと IPv6 アドレスの両方をサポートします。

構文

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

パラメーター

[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 プロトコルの Web サーバーで使用される既定のポートとして定義されているポート 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 を 返し、これらのバッファーが呼び出し元によって提供された場合、 LocalAddress パラメーターと RemoteAddress パラメーターが入力されます。

呼び出しが失敗した場合は、 FALSE が返されます。 WSAGetLastError を呼び出して、拡張エラー情報を取得できます。

リターン コード 説明
WSAEHOSTUNREACH
nodename パラメーターとして渡されたホストに到達できませんでした。
WSAEINVAL
無効なパラメーターが関数に渡されました。 nodename パラメーターまたは servicename パラメーターを NULL にすることはできません。 予約済みパラメーターは NULL である必要があります。
WSAENOBUFS
十分なメモリを割り当てませんでした。
WSAENOTSOCK
無効なソケットが関数に渡されました。 s パラメーターは、INVALID_SOCKETまたは NULL にすることはできません。
WSAETIMEDOUT
タイムアウト パラメーターを超える前に、リモート アプリケーションからの応答を受信できませんでした。

注釈

WSAConnectByName は、特定のポート上のリモート ホストへの迅速かつ透過的な接続を可能にするために提供されます。 IPv6 と IPv4 の両方のバージョンと互換性があります。

IPv6 と IPv4 の両方の通信を有効にするには、次の方法を使用します。

  • WSAConnectByName を呼び出す前に、IPV6_V6ONLY ソケット オプションを無効にするには、AF_INET6 アドレス ファミリ用に作成されたソケットで setsockopt 関数を呼び出す必要があります。 これは、レベル パラメーターを IPPROTO_IPV6 に設定し (IPPROTO_IPV6 ソケット オプションを参照)、optname パラメーターを IPV6_V6ONLY に設定し、optvalue パラメーター値を 0 に設定して、ソケットで setsockopt 関数を呼び出すことによって実現されます。

WSAConnectByName には制限があります。これは、SOCK_STREAM型のソケットなど、接続指向のソケットに対してのみ機能します。 関数は、重複した I/O または非ブロッキング動作をサポートしていません。 ソケットが非ブロッキング モードの場合でも、WSAConnectByName はブロックします。

WSAConnectByName では、接続の確立中にユーザー指定のデータはサポートされません。 この呼び出しでは、FLOWSPEC 構造体もサポートされていません。 これらの機能が必要な場合は、代わりに WSAConnect を使用する必要があります。

Windows 10より前のバージョンでは、アプリケーションが特定のローカル アドレスまたはポートにバインドする必要がある場合、WSAConnectByName へのソケット パラメーターはバインドされていないソケットである必要があるため、WSAConnectByName を使用できません。

この制限はWindows 10削除されました。

RemoteAddress パラメーターと LocalAddress パラメーターは、ジェネリック データ型である SOCKADDR 構造体を指します。 WSAConnectByName が呼び出されると、使用されているネットワーク プロトコルまたはアドレス ファミリに固有のソケット アドレスの種類が実際にこれらのパラメーターに渡されることが期待されます。 そのため、IPv4 アドレスの場合、remoteAddress パラメーターと LocalAddress パラメーターとして、sockaddr_in構造体へのポインターが SOCKADDR へのポインターにキャストされます。 IPv6 アドレスの場合、remoteAddress パラメーターと LocalAddress パラメーターとして、sockaddr_in6構造体へのポインターが SOCKADDR へのポインターにキャストされます。

WSAConnectByName 関数が TRUE を返すと、ソケット s は接続されているソケットの既定の状態になります。 ソケット 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.1およびWindows 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 ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI または Unicode バージョンを自動的に選択するエイリアスとして WSAConnectByName を定義します。 encoding-neutral エイリアスの使用を encoding-neutral ではないコードと混在すると、コンパイル エラーまたはランタイム エラーが発生する不一致が発生する可能性があります。 詳細については、「 関数プロトタイプの規則」を参照してください。

要件

要件
サポートされている最小のクライアント Windows 8.1、Windows Vista [デスクトップ アプリ |UWP アプリ]
サポートされている最小のサーバー Windows Server 2008 [デスクトップ アプリ | UWP アプリ]
対象プラットフォーム Windows
ヘッダー winsock2.h
Library Ws2_32.lib
[DLL] Ws2_32.dll

こちらもご覧ください

IPPROTO_IPV6 ソケット オプション

Sockaddr

WSAConnect

WSAConnectByList

WSAGetLastError

getaddrinfo

getpeername

getsockname

setsockopt