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
識別未連接套接字的描述項。
[in] nodename
NULL 終止的字串,其中包含要針對 IPv4 或 IPv6 連線之主機的名稱或主機的 IP 位址。
[in] servicename
NULL 終止的字串,其中包含要連線至 IPv4 或 IPv6 之主機的服務名稱或目的地埠。
服務名稱是埠號碼的字串別名。 例如,「HTTP」 是因特網工程工作組 (IETF) 所定義之埠 80 的別名,做為 Web 伺服器用於 HTTP 通訊協定的預設埠。 未指定埠號碼時 ,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。
傳回值
如果已建立連線,如果呼叫端提供這些緩衝區, WSAConnectByName 會傳回 TRUE 和 LocalAddress 和 RemoteAddress 參數。
如果呼叫失敗,則會傳回 FALSE 。 接著可以呼叫 WSAGetLastError 以取得擴充的錯誤資訊。
傳回碼 | Description |
---|---|
|
無法連線到傳遞為 nodename 參數的主機。 |
|
無效的參數已傳遞至 函式。 nodename 或 servicename 參數不得為 NULL。 Reserved 參數必須是 NULL。 |
|
無法配置足夠的記憶體。 |
|
傳遞至函式的套接字無效。 s 參數不得INVALID_SOCKET或 NULL。 |
|
超過 逾 時參數之前,未收到來自遠端應用程式的回應。 |
備註
提供 WSAConnectByName ,以便快速且透明地連線到特定埠上的遠端主機。 它與 IPv6 和 IPv4 版本相容。
若要啟用 IPv6 和 IPv4 通訊,請使用下列方法:
- 在為AF_INET6位址系列建立的套接字上呼叫 setsockopt 函式,才能在呼叫 WSAConnectByName 之前停用 IPV6_V6ONLY 套接字選項。 這可藉由呼叫套接字上的 setsockopt 函式,並將 level 參數設定為 IPPROTO_IPV6 ( 請參閱 IPPROTO_IPV6 Socket Options) 、 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 市集應用程式支援 WSAConnectByNameW 函式,Windows 8.1、Windows Server 2012 R2 及更新版本。
範例
使用 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 應用程式] |
目標平台 | Windows |
標頭 | winsock2.h |
程式庫 | Ws2_32.lib |
Dll | Ws2_32.dll |