bind 関数 (winsock.h)

バインド関数は、ローカル アドレスをソケットに関連付けます。

構文

int bind(
  [in] SOCKET         s,
       const sockaddr *addr,
  [in] int            namelen
);

パラメーター

[in] s

バインドされていないソケットを識別する記述子。

addr

バインドされたソケット に割り当てるローカル アドレスの sockaddr 構造体へのポインター。

[in] namelen

addr が指す値の長さ (バイト単位)。

戻り値

エラーが発生しない場合、 bind は 0 を返します。 それ以外の場合はSOCKET_ERRORを返し、 WSAGetLastError を呼び出すことで特定のエラー コードを取得できます。

エラー コード 意味
WSANOTINITIALIZED
メモ この関数を使用する前に、 WSAStartup 呼び出しが正常に行われる必要があります。
 
WSAENETDOWN
ネットワーク サブシステムが失敗しました。
WSAEACCES
アクセス許可で禁じられた方法でソケットにアクセスしようとしました。

このエラーは、 setsockopt オプション SO_BROADCASTが有効になっていないために、nn がデータグラム ソケットをブロードキャスト アドレスにバインドしようとして失敗した場合に返されます。

WSAEADDRINUSE
Only one usage of each socket address (protocol/network address/port) is normally permitted.

このエラーは、コンピューター上のプロセスが既に同じ完全修飾アドレスにバインドされていて、SO_REUSEADDRでアドレスを再利用できるようにソケットがマークされていない場合に返されます。 たとえば、 name パラメーターで指定された IP アドレスとポートは、別のアプリケーションで使用されている別のソケットに既にバインドされています。 詳細については、「SOL_SOCKET ソケット オプション 」リファレンスの「SO_REUSEADDR ソケット オプション」、「 SO_REUSEADDRとSO_EXCLUSIVEADDRUSEの使用」、「 SO_EXCLUSIVEADDRUSE」を参照してください。

WSAEADDRNOTAVAIL
要求されたアドレスは、そのコンテキストでは有効ではありません。

このエラーは、 name パラメーターで指定されたアドレスが、このコンピューター上の有効なローカル IP アドレスでない場合に返されます。

WSAEFAULT
呼び出しでポインター引数を使用しようとしたときに、システムにより、無効なポインター アドレスが検出されました。

このエラーは、name パラメーターが NULL、name または namelen パラメーターがユーザー アドレス空間の有効な部分ではない、namelen パラメーターが小さすぎる、関連するアドレス ファミリのアドレス形式が正しくない、または名前で指定されたメモリ ブロックの最初の 2 バイトがソケット記述子関連付けられているアドレス ファミリと一致しない場合に返されます。

WSAEINPROGRESS
ブロックしている Windows Sockets 1.1 呼び出しが進行中であるか、サービス プロバイダーがコールバック関数を処理しています。
WSAEINVAL
無効な引数が指定されました。

このエラーは、既にアドレスにバインドされているソケット s から返されます。

WSAENOBUFS
通常、 WSAENOBUFS は、バインドに割り当てるのに十分なエフェメラル ポートがないことを示しています。
WSAENOTSOCK
ソケットではないものに対して操作が試行されました。

このエラーは、 s パラメーターの記述子がソケットでない場合に返されます。

注釈

バインド関数は、後続の listen 関数の呼び出しの前に、接続されていないソケットで必要です。 通常は、接続指向 (ストリーム) またはコネクションレス (データグラム) ソケットにバインドするために使用されます。 バインド関数を使用して生のソケットにバインドすることもできます (ソケットは、type パラメーターを SOCK_RAW に設定してソケット関数を呼び出すことによって作成されました)。 バインド関数は、送信操作の前に接続、ConnectExWSAConnect、WSAConnectByList、または WSAConnectByName 関数の後続の呼び出しの前に、接続されていないソケットでも使用できます。

ソケット関数の呼び出しでソケットが作成されると、その ソケット は名前空間 (アドレス ファミリ) に存在しますが、名前は割り当てされません。 バインド関数を使用して、名前のないソケットにローカル名を割り当てることで、ソケットのローカル関連付けを確立します。

インターネット アドレス ファミリを使用する場合、名前は次の 3 つの部分で構成されます。

  • アドレス ファミリ。
  • ホスト アドレス。
  • アプリケーションを識別するポート番号。

Windows ソケット 2 では、 name パラメーターは sockaddr 構造体へのポインターとして厳密に解釈されません。 これは、Windows ソケット 1.1 の互換性のためにこの方法でキャストされます。 サービス プロバイダーは、サイズ namelen のメモリ ブロックへのポインターとして自由に見 なします。 このブロックの最初の 2 バイト (sockaddr 構造体のsa_family メンバー、sockaddr_in構造体のsin_family メンバー、またはsockaddr_in6構造体のsin6_family メンバーに対応) には、ソケットの作成に使用されたアドレス ファミリが含まれている必要があります。 それ以外の場合は、エラー WSAEFAULT が発生します。

アプリケーションが割り当てられているローカル アドレスを気にしない場合は、IPv4 ローカル アドレスにINADDR_ANY定数値を指定するか、name パラメーターの sa_data メンバーで IPv6 ローカル アドレスにin6addr_any定数値を指定します。 これにより、基になるサービス プロバイダーは適切なネットワーク アドレスを使用できるため、 マルチホーム ホスト (つまり、複数のネットワーク インターフェイスとアドレスを持つホスト) が存在するアプリケーション プログラミングが簡略化される可能性があります。

TCP/IP の場合、ポートがゼロとして指定されている場合、サービス プロバイダーは動的クライアント ポート範囲からアプリケーションに一意のポートを割り当てます。 Windows Vista 以降では、動的クライアント ポート範囲は 49152 ~ 65535 の値です。 これは、動的クライアント ポート範囲が 1025 ~ 5000 の値であった Windows Server 2003 以前からの変更です。 クライアントの動的ポート範囲の最大値は、次のレジストリ キーの値を設定することで変更できます。

HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

MaxUserPort レジストリ値は、動的クライアント ポート範囲の最大値に使用する値を設定します。 この設定を有効にするには、コンピューターを再起動する必要があります。

Windows Vista 以降では、 netsh コマンドを使用して動的クライアント ポート範囲を表示および変更できます。 動的クライアント ポート範囲は、UDP と TCP、および IPv4 と IPv6 に対して異なる方法で設定できます。 詳細については、「 KB 929851」を参照してください。

アプリケーションでは、bind を呼び出した後に getsockname を使用して、ソケットに割り当てられているアドレスとポートを学習できます。 インターネット アドレスが INADDR_ANY または in6addr_any と等しい場合、ホストがマルチホームの場合に複数のアドレスを有効にできるため、ソケットが接続されるまで は、必ずしもアドレスを指定 できません。 ポート 0 以外の特定のポート番号へのバインドは、ローカル コンピューター上でそのポート番号を既に使用している別のソケットと競合する危険性があるため、クライアント アプリケーションでは推奨されません。

メモ SO_EXCLUSIVEADDRUSE または SO_REUSEADDR ソケット オプションで バインド を使用する場合は、 バインド を実行する前にソケット オプションを設定して、何らかの影響を与える必要があります。 詳細については、「 SO_EXCLUSIVEADDRUSE 」および「 SO_REUSEADDRとSO_EXCLUSIVEADDRUSEの使用」を参照してください。

 

マルチキャスト操作の場合は、 bind 関数を呼び出してソケットをローカル IP アドレスに関連付け、マルチキャスト グループに参加することをお勧めします。 この操作の順序は必須ではありませんが、強くお勧めします。 そのため、マルチキャスト アプリケーションでは、最初にローカル コンピューター上の IPv4 または IPv6 アドレス、ワイルドカード IPv4 アドレス (INADDR_ANY)、またはワイルドカード IPv6 アドレス (in6addr_any) を選択します。 その後、マルチキャスト アプリケーションは、name パラメーターの sa_data メンバー内の このアドレスを使用してバインド関数を呼び出し、ローカル IP アドレスをソケットに関連付けます。 ワイルドカード アドレスが指定されている場合、Windows は使用するローカル IP アドレスを選択します。 バインド関数が完了すると、アプリケーションは目的のマルチキャスト グループに参加します。 マルチキャスト グループに参加する方法の詳細については、「 マルチキャスト プログラミング」のセクションを参照してください。 このソケットを使用すると、recv、recvfromWSARecv、WSARecvExWSARecvFrom、またはLPFN_WSARECVMSG (WSARecvMsg) 関数を使用して、マルチキャスト グループからマルチキャスト パケットを受信できます。

バインド 関数は 通常、マルチキャスト グループへの送信操作には必要ありません。 ソケットがまだバインドされていない場合、 sendtoWSASendMsg、および WSASendTo 関数は、ソケットをワイルドカード アドレスに暗黙的にバインドします。 バインド関数は、暗黙的な バインド を実行せず、接続されたソケットでのみ許可される send 関数または WSASend 関数を使用する前に必要です。つまり、接続するにはソケットが既にバインドされている必要があります。 バインド関数は、アプリケーションが複数のネットワーク インターフェイスとローカル IP アドレスを持つローカル コンピューター上の特定のローカル IP アドレスを選択する場合に、sendtoWSASendMsg、または WSASendTo 関数を使用する送信操作の前に使用できます。 それ以外の場合、 sendtoWSASendMsg、または WSASendTo 関数を使用してワイルドカード アドレスに暗黙的にバインドすると、送信操作に別 ローカル IP アドレスが使用される可能性があります。

メモbind などのブロッキング Winsock 呼び出しを発行する場合、Winsock は、呼び出しを完了する前にネットワーク イベントを待機する必要がある場合があります。 Winsock は、この状況でアラート可能な待機を実行します。この待機は、同じスレッドでスケジュールされた非同期プロシージャ 呼び出し (APC) によって中断される可能性があります。 同じスレッドで進行中の Winsock 呼び出しを中断した APC 内で別のブロック Winsock 呼び出しを発行すると、未定義の動作が発生し、Winsock クライアントが試行してはなりません。
 

IrDA ソケットに関する注意事項

  • Af_irda.h ヘッダー ファイルは明示的に含まれている必要があります。
  • ローカル名は IrDA では公開されません。 そのため、IrDA クライアント ソケットは、接続関数の前にバインド関数を呼び出してはなりません。 IrDA ソケットが bind を使用してサービス名にバインドされていた場合、 接続 関数は SOCKET_ERROR で失敗します。
  • サービス名が "LSAP-SELxxx" という形式の場合(xxx は 1 から 127 の範囲の 10 進整数)、アドレスはサービス名ではなく特定の LSAP-SEL xxx を示します。 このようなサービス名を使用すると、サーバー アプリケーションは、最初に ISA サービス名クエリを実行せずに、特定の LSAP-SEL に送信された受信接続を受け入れ、関連付けられた LSAP-SEL を取得できます。 このサービス名の種類の 1 つの例は、IAS をサポートしていない Windows 以外のデバイスです。

Windows Phone 8: この関数は、Windows Phone 8 以降のWindows Phone ストア アプリでサポートされています。

Windows 8.1Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストア アプリでサポートされています。

次の例では、 bind 関数の使用方法を示します。 bind 関数を使用する別の例については、「winsock ではじめにする」を参照してください。

#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")

int main()
{

    // Declare some variables
    WSADATA wsaData;

    int iResult = 0;            // used to return function results

    // the listening socket to be created
    SOCKET ListenSocket = INVALID_SOCKET;

    // The socket address to be passed to bind
    sockaddr_in service;

    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"Error at WSAStartup()\n");
        return 1;
    }
    //----------------------
    // Create a SOCKET for listening for 
    // incoming connection requests
    ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ListenSocket == INVALID_SOCKET) {
        wprintf(L"socket function failed with error: %u\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port for the socket that is being bound.
    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr("127.0.0.1");
    service.sin_port = htons(27015);

    //----------------------
    // Bind the socket.
    iResult = bind(ListenSocket, (SOCKADDR *) &service, sizeof (service));
    if (iResult == SOCKET_ERROR) {
        wprintf(L"bind failed with error %u\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    else
        wprintf(L"bind returned success\n");

    WSACleanup();
    return 0;
}

要件

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

こちらもご覧ください

マルチキャスト プログラミング

SOL_SOCKET ソケット オプション

SO_EXCLUSIVEADDRUSE

TCP/IP 生ソケット

SO_REUSEADDRとSO_EXCLUSIVEADDRUSEの使用

WSACancelBlockingCall

Winsock 関数

Winsock リファレンス

connect

getsockname

listen

setsockopt

Sockaddr

socket