bind 函式 (winsock.h)

bind 函式會將本機位址與套接字產生關聯。

語法

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

參數

[in] s

識別未系結套接字的描述項。

addr

要指派給系結套接字之本機位址 之 sockaddr 結構的指標。

[in] namelen

附加元件所指向值的長度,以位元組為單位。

傳回值

如果沒有發生錯誤, 系結 會傳回零。 否則,它會傳回SOCKET_ERROR,而且可以呼叫 WSAGetLastError 來擷取特定的錯誤碼。

錯誤碼 意義
WSANOTINITIALISED
注意 使用此函式之前,必須先進行成功的 WSAStartup 呼叫。
 
WSAENETDOWN
網路子系統失敗。
WSAEACCES
嘗試透過其訪問許可權禁止的方式來存取套接字。

如果 nn 嘗試將數據報套接字系結至廣播地址失敗,就會傳回此錯誤,因為 未啟用 setockopt 選項SO_BROADCAST。

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 參數太小、name 參數包含關聯位址系列不正確的位址格式,或是名稱所指定記憶體區塊的前兩個字節不符合與套接字描述元相關聯的位址系列

WSAEINPROGRESS
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或者服務提供者仍在處理回呼函式。
WSAEINVAL
提供的引數無效。

這個錯誤會傳回套接字 s 已系結至位址。

WSAENOBUFS
一般而言, WSAENOBUFS 表示沒有足夠的暫時埠來配置系結。
WSAENOTSOCK
嘗試在不是套接字的某個專案上執行作業。

如果 s 參數中的描述項不是套接字,就會傳回此錯誤。

備註

在接函式的後續呼叫之前,在未連接的套接字上需要系結函式。 它通常用來系結至連接導向 (數據流) 或無連接 (數據報) 套接字。 系結函式也可以用來系結至原始套接字, (套接字是藉由呼叫別參數設為 SOCK_RAW) 來建立套接字。 在傳送作業之前,系函式也可以在未連線的套接字上使用,再呼叫 ConnectExWSAConnectWSAConnectByListWSAConnectByName 函式。

使用對套接字函式的呼叫建立 套接字 時,它存在於命名空間中 (位址系列) ,但它沒有指派名稱給它。 使用 bind 函式,將本機名稱指派給未命名的套接字,以建立套接字的本機關聯。

使用因特網位址系列時,名稱是由三個部分所組成:

  • 位址系列。
  • 主機位址。
  • 識別應用程式的埠號碼。

在 Windows Sockets 2 中, name 參數不會嚴格解譯為 sockaddr 結構的指標。 它以這種方式轉換 Windows Sockets 1.1 相容性。 服務提供者可以將其視為 namelen 記憶體區塊的指標。 此區塊中的前 2 個字節 (對應至 sockaddr 結構的sa_family成員、sockaddr_in 結構的sin_family成員,或sockaddr_in6結構) sin6_family成員必須包含用來建立套接字的位址系列。 否則,會發生錯誤 WSAEFAULT。

如果應用程式不關心指派的本機位址,請在名稱參數sa_data成員中指定IPv4 本機位址的常數值INADDR_ANY或 IPv6 本機位址的常數值in6addr_any 這可讓基礎服務提供者使用任何適當的網路位址,可能會簡化應用程式程序設計,其存在於 多路 主機 (,也就是具有多個網路介面的主機和位址) 。

針對 TCP/IP,如果埠指定為零,服務提供者會從動態用戶端埠範圍將唯一埠指派給應用程式。 在 Windows Vista 和更新版本上,動態用戶端埠範圍是介於 49152 和 65535 之間的值。 這是 Windows Server 2003 和更早版本的變更,其中動態用戶端埠範圍是介於 1025 和 5000 之間的值。 藉由在下列登錄機碼下設定值,即可變更客戶端動態埠範圍的最大值:

HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

MaxUserPort 登錄值會設定要用於動態用戶端埠範圍最大值的值。 您必須重新啟動電腦,此設定才會生效。

在 Windows Vista 和更新版本上,可以使用 netsh 命令來檢視和變更動態用戶端埠範圍。 動態用戶端埠範圍可以針對UDP和TCP以不同方式設定,也適用於IPv4和IPv6。 如需詳細資訊,請參閱 KB 929851

應用程式可以在呼叫 bind 之後使用 getsockname,以瞭解已指派給套接字的位址和埠。 如果因特網位址等於 INADDR_ANYin6addr_any則取得ockname 在連線套接字之前不一定提供地址,因為如果主機多路連接,則數個位址可能有效。 用戶端應用程式不建議系結至埠 0 以外的特定埠號碼,因為本機計算機上已使用該埠號碼的另一個套接字發生衝突。

注意 搭配SO_EXCLUSIVEADDRUSE或SO_REUSEADDR套接字選項使用 系結 時,必須先設定套接字選項,才能執行 系結 以有任何影響。 如需詳細資訊,請參閱SO_EXCLUSIVEADDRUSE和使用SO_REUSEADDR和SO_EXCLUSIVEADDRUSE

 

對於多播作業,慣用的方法是呼叫 系結 函式,以將套接字與本機 IP 位址產生關聯,然後加入多播群組。 雖然此作業順序並非必要,但強烈建議您這麼做。 因此,多播應用程式會先選取本機計算機上的 IPv4 或 IPv6 位址、通配符 IPv4 位址 (INADDR_ANY) ,或通配符 IPv6 位址 (in6addr_any) 。 多播應用程式接著會在 name 參數的 sa_data 成員中,呼叫具有這個位址的系結函式,以將本機 IP 位址與套接字產生關聯。 如果指定通配符位址,則 Windows 會選取要使用的本機 IP 位址。 系結函式完成後,應用程式會接著加入感興趣的多播群組。 如需如何加入多播群組的詳細資訊,請參閱 多播程序設計一節。 接著,此套接字可用來使用 recv、recvromWSARecv、WSARecvExWSARecvFromLPFN_WSARECVMSG (WSARecvMsg) 函式,從多播群組接收多播封包。

將作業傳送至多播群組時,通常不需要 系結 函式。 如果套接字尚未系結, sendtoWSASendMsgWSASendTo 函式會隱含地將套接字系結至通配符位址。 在傳送或WSASend 函式的使用之前,必須先有系結函式,這些函式不會執行隱含系結,而且只允許在連線的套接字上,這表示套接字必須已經系結,才能連線。 如果使用 sendtoWSASendMsgWSASendTo 函式傳送作業,如果應用程式想要在本機電腦上選取具有多個網路介面和本機 IP 位址的特定本機 IP 位址,可以使用系結函式。 否則,隱含系結至使用 sendtoWSASendMsgWSASendTo 函式的通配符位址,可能會導致不同的本機 IP 位址用於傳送作業。

注意 發出封鎖的 Winsock 呼叫,例如 系結時,Winsock 可能需要等候網路事件,才能完成呼叫。 Winsock 會在這種情況中執行可警示的等候,而異步過程調用 (APC) 排程在同一個線程上,可能會中斷。 在 APC 內發出另一個封鎖 Winsock 呼叫,中斷相同線程上持續封鎖 Winsock 呼叫會導致未定義的行為,而且永遠不會由 Winsock 客戶端嘗試。
 

IrDA 套接字注意事項

  • 必須明確包含 Af_irda.h 頭檔。
  • 本機名稱不會在 IrDA 中公開。 因此,IrDA 用戶端套接字絕對不能在 connect 函式之前呼叫 bind 函式。 如果 IrDA 套接字先前使用 系結系結至服務名稱, 則 connect 函式將會失敗,並SOCKET_ERROR。
  • 如果服務名稱的格式為 「LSAP-SELxxx」,其中 xxx 是範圍 1-127 中的十進位整數,則位址會指出特定的 LSAP-SEL xxx,而不是服務名稱。 這類服務名稱可讓伺服器應用程式接受導向至特定 LSAP-SEL 的連入連線,而不需要先執行 ISA 服務名稱查詢,以取得相關聯的 LSAP-SEL。 此服務名稱類型的其中一個範例是不支援 IAS 的非 Windows 裝置。

Windows Phone 8:Windows Phone 8 和更新版本 Windows Phone 市集應用程式支援此函式。

Windows 8.1Windows Server 2012 R2:Windows 市集應用程式支援此函式,Windows 8.1、Windows Server 2012 R2 及更新版本。

範例

下列範例示範系 函式的使用。 如需使用系結函式的另一個範例,請參閱使用 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)
程式庫 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