bind 函式 (winsock2.h)
系結 函式會將本機位址與套接字產生關聯。
語法
int WSAAPI bind(
[in] SOCKET s,
[in] const sockaddr *name,
[in] int namelen
);
參數
[in] s
識別未系結套接字的描述項。
[in] name
要指派給系結套接字之本機位址之 sockaddr 的指標 結構。
[in] namelen
名稱 參數所指向之值的長度,以位元組為單位。
傳回值
如果沒有發生錯誤,系結 會傳回零。 否則,它會傳回SOCKET_ERROR,而且可以呼叫 WSAGetLastError來擷取特定的錯誤碼。
錯誤碼 | 意義 |
---|---|
注意 在使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。
|
|
網路子系統失敗。 | |
嘗試以其訪問許可權禁止的方式存取套接字。
如果嘗試將數據報套接字系結至廣播地址失敗,就會傳回此錯誤,因為未啟用 setsockopt 選項SO_BROADCAST。 |
|
通常只允許每個套接字位址的一個用法(通訊協定/網路位址/埠)。
如果計算機上的進程已經系結至相同的完整位址,而且套接字尚未標示為允許使用 SO_REUSEADDR 重複使用位址,則會傳回此錯誤。 例如,名稱 參數中指定的IP位址和埠已經系結至另一個應用程式所使用的另一個套接字。 如需詳細資訊,請參閱 SOL_SOCKET 套接字選項 參考中的 SO_REUSEADDR 套接字選項,使用 SO_REUSEADDR 和 SO_EXCLUSIVEADDRUSE和 SO_EXCLUSIVEADDRUSE。 |
|
要求位址在其內容中無效。
如果 名稱所指向的指定位址 參數不是這部計算機上的有效本機IP位址,就會傳回此錯誤。 |
|
系統在嘗試在呼叫中使用指標自變數時偵測到無效的指標位址。
如果 名稱 參數為 NULL,則會傳回此錯誤。 名稱 或 namelen 參數不是使用者位址空間的有效部分、namelen 參數太小、名稱 參數包含相關聯位址系列不正確的位址格式,或 名稱所指定記憶體區塊的前兩個字節 不符合相關聯的位址系列使用套接字描述元 s。 |
|
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。 | |
已提供無效的自變數。
這個錯誤會傳回套接字 已系結至位址。 |
|
無法執行套接字上的作業,因為系統沒有足夠的緩衝區空間或佇列已滿。
這個錯誤傳回的緩衝區不足,或連線太多。 |
|
在不是套接字的某個項目上嘗試作業。
如果 參數中的描述項不是套接字,則會傳回此錯誤。 |
言論
在後續呼叫 接聽 函式之前,必須先在未連接的套接字上 系結 函式。 它通常用來系結至連線導向 (stream) 或無連接 (datagram) 套接字。 系結 函式也可以用來系結至原始套接字(套接字是藉由呼叫 套接字 函式,並將 類型 參數設為 SOCK_RAW 所建立)。 系結 函式也可以在未連接套接字上使用,之後再呼叫 connect、ConnectEx、WSAConnect、WSAConnectByList或 WSAConnectByName 函式,再傳送作業。
使用對 套接字 函式的呼叫建立套接字時,它存在於命名空間(位址系列),但沒有指派名稱給它。 使用 系結 函式,將本機名稱指派給未命名的套接字,以建立套接字的本機關聯。
使用因特網位址系列時,名稱包含三個部分:
- 位址系列。
- 主機位址。
- 識別應用程式的埠號碼。
在 Windows Sockets 2 中,名稱 參數不會嚴格解譯為 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。
應用程式可以在呼叫 系結 之後,使用 getsockname,以瞭解已指派給套接字的位址和埠。 如果因特網位址等於 INADDR_ANY 或 in6addr_any,getsockname 不一定提供位址,直到套接字連線為止,因為如果主機多路連接,數個位址可能有效。 用戶端應用程式不建議系結至埠 0 以外的特定通訊埠號碼,因為本機計算機上已有該埠號碼與另一個套接字發生衝突的危險。
對於多播作業,慣用的方法是呼叫 系結 函式,以將套接字與本機 IP 位址產生關聯,然後加入多播群組。 雖然這項作業順序並非必要,但強烈建議這麼做。 因此,多播應用程式會先選取本機計算機上的IPv4或IPv6位址、通配符IPv4 位址(INADDR_ANY),或通配符 IPv6 位址(in6addr_any)。 然後,多播應用程式會呼叫 系結 函式,並在 名稱 參數的 sa_data 成員中,將此位址與套接字產生關聯。 如果指定通配符位址,則 Windows 會選取要使用的本機 IP 位址。 系結 函式完成之後,應用程式會接著加入感興趣的多播群組。 如需如何加入多播群組的詳細資訊,請參閱多播程式設計 一節,。 然後,您可以使用 recv、從、WSARecv,從多播群組接收多播封包 、WSARecvEx、WSARecvFrom或 LPFN_WSARECVMSG (WSARecvMsg) 函式。
系結 函式通常不需要傳送作業至多播群組。 sendto、WSASendMsg和 WSASendTo 函式會在套接字尚未系結時隱含地將套接字系結至通配符位址。 使用 傳送 或 WSASend 函式之前,必須先 系結 函式,這些函式不會執行隱含系結,而且只能在連接的套接字上允許,這表示套接字必須已系結,才能連接。 如果使用 sendto、WSASendMsg或 WSASendTo 功能,如果應用程式想要在具有多個網路介面和本機 IP 位址的本機計算機上選取特定本機 IP 位址,則 系結 函式。 否則,使用 sendto sendto、WSASendMsg 或 WSASendTo 函式,隱含系結至通配符位址可能會導致不同的本機 IP 位址用於傳送作業。
IrDA 套接字的注意事項
- 必須明確包含 Af_irda.h 頭檔。
- IrDA 中不會公開本機名稱。 因此,IrDA 用戶端套接字絕不能在 連接 函式之前呼叫 系結 函式。 如果 IrDA 套接字先前使用系結 系結系結至服務名稱,連線 函式將會失敗併產生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.1 和 Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 和更新版本上支援 Windows 市集應用程式。
例子
下列範例示範如何使用 系結 函式。 如需使用 系結 函式的另一個範例,請參閱 開始使用 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 應用程式] |
目標平臺 | 窗戶 |
標頭 | winsock2.h (包括 Winsock2.h) |
連結庫 | Ws2_32.lib |
DLL | Ws2_32.dll |
另請參閱
使用SO_REUSEADDR和SO_EXCLUSIVEADDRUSE