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
識別未連接套接字的描述項。
[in] nodename
NULL終止字串,其中包含要連線至 IPv4 或 IPv6 之主機的名稱或主機的 IP 位址。
[in] servicename
NULL終止字串,其中包含要連線至 IPv4 或 IPv6 之主機的服務名稱或目的地埠。
服務名稱是埠號碼的字串別名。 例如,「HTTP」 是 Internet Engineering Task Force (IETF) 所定義之埠 80 的別名,作為 Web 伺服器用於 HTTP 通訊協定的預設埠。 未指定埠號碼時,servicename 參數的可能值列在下列檔案中:
%WINDIR%\system32\drivers\etc\services
[in, out] LocalAddressLength
在輸入上,呼叫端所提供之 LocalAddress 緩衝區的大小指標,以位元組為單位。 在輸出中,SOCKADDR 大小指標, 儲存在 LocalAddress 緩衝區中儲存的本機位址,在呼叫成功完成時填入。
[out] LocalAddress
接收連線本機位址之 SOCKADDR 結構的指標。 參數的大小正好是localAddressLength 中所傳回的大小,。 這是由 getsockname 函式傳回的相同資訊。 此參數可以
[in, out] RemoteAddressLength
在輸入時,RemoteAddress 呼叫端提供的緩衝區大小指標,以位元組為單位。 在輸出中,SOCKADDR 的大小指標, 儲存在 RemoteAddress 緩衝區的遠端位址在呼叫成功完成時填入。
[out] RemoteAddress
接收連線遠端位址之 SOCKADDR 結構的指標。 這是由 getpeername 函式
[in] timeout
在中止呼叫之前,等候遠端應用程式回應的時間,以毫秒為單位。
Reserved
保留給未來的實作。 這個參數必須設定為 NULL。
傳回值
如果已建立連線,WSAConnectByName 會傳回 true TRUE 和 LocalAddress 和 RemoteAddress 參數,如果呼叫者提供這些緩衝區,則會填入這些緩衝區。
如果呼叫失敗,則會傳回 FALSE
傳回碼 | 描述 |
---|---|
|
無法連線到當做 nodename 參數傳遞的主機。 |
|
無效的參數已傳遞至函式。 nodename 或 servicename 參數不得 NULL。 保留 參數必須 NULL。 |
|
無法配置足夠的記憶體。 |
|
傳遞無效的套接字至函式。 的 參數不得 INVALID_SOCKET 或 NULL。 |
|
在超過 逾時 參數之前,未收到來自遠端應用程式的回應。 |
言論
提供 WSAConnectByName,以啟用特定埠上遠端主機的快速透明連線。 它與 IPv6 和 IPv4 版本相容。
若要啟用 IPv6 和 IPv4 通訊,請使用下列方法:
- setockopt 函式必須在為AF_INET6位址系列建立的套接字上呼叫,才能在呼叫 WSAConnectByName之前停用 IPV6_V6ONLY 套接字選項。 這可藉由呼叫套接字上的 setsockopt 函式,並將 層級 參數設定為 IPPROTO_IPV6 (請參閱 IPPROTO_IPV6 套接字選項)、optname 參數設定為 IPV6_V6ONLY,並將 optvalue 參數值設定為零。
WSAConnectByName 有限制:它只適用於連線導向的套接字,例如類型SOCK_STREAM。 函式不支援重疊的 I/O 或非封鎖行為。 WSAConnectByName 會封鎖,即使套接字處於非封鎖模式也一樣。
WSAConnectByName 在建立連線期間不支援使用者提供的數據。 此呼叫也不支援 FLOWSPEC 結構。 如果需要這些功能,則必須改用 WSAConnect 。
在 Windows 10 之前的版本中,如果應用程式需要系結至特定的本機位址或埠,則無法使用 WSAConnectByName,因為套接字參數 WSAConnectByName 必須是未系結的套接字。
此限制已移除 Windows 10。
RemoteAddress 和 LocalAddress 參數指向 SOCKADDR 結構,這是泛型數據類型。 呼叫 WSAConnectByName 時,預期會實際傳入這些參數中所使用的網路通訊協定或位址系列特定的套接字地址類型。 因此,針對 IPv4 位址,sockaddr_in 結構的指標會轉換成 SOCKADDR 指標, 做為 RemoteAddress 和 LocalAddress 參數。 針對 IPv6 位址,sockaddr_in6 結構的指標會轉換成 SOCKADDR 指標, 做為 RemoteAddress 和 LocalAddress 參數。
當 WSAConnectByName 函式傳回 true時,套接字 處於連線套接字的默認狀態。 套接字 在套接字上設定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 );
Windows 8.1 和 Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更新版本的 Windows 市集應用程式支援 WSAConnectByNameW 功能。
例子
使用 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 預處理器常數的定義,將 WSAConnectByName 定義為自動選取此函式的 ANSI 或 Unicode 版本。 混合使用編碼中性別名與非編碼中性的程序代碼,可能會導致編譯或運行時間錯誤不符。 如需詳細資訊,請參閱函式原型的
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式] |
支援的最低伺服器 | Windows Server 2008 [傳統型應用程式 |UWP 應用程式] |
目標平臺 | 窗戶 |
標頭 | winsock2.h |
連結庫 | Ws2_32.lib |
DLL | Ws2_32.dll |