connect 函式 (winsock2.h)
connect函式會建立與指定通訊端的連線。
語法
int WSAAPI connect(
[in] SOCKET s,
[in] const sockaddr *name,
[in] int namelen
);
參數
[in] s
識別未連接通訊端的描述項。
[in] name
應該建立連接之 sockaddr 結構的指標。
[in] namelen
name參數所指向之 sockaddr結構的長度,以位元組為單位。
傳回值
如果沒有發生錯誤, connect 會傳回零。 否則,它會傳回SOCKET_ERROR,而且可以呼叫 WSAGetLastError來擷取特定的錯誤碼。
在封鎖通訊端上,傳回值表示連線嘗試成功或失敗。
使用非封鎖通訊端時,無法立即完成連線嘗試。 在此情況下, connect 會傳回SOCKET_ERROR,而 WSAGetLastError 會傳回 WSAEWOULDBLOCK。 在此情況下,有三個可能的案例:
- 藉由檢查通訊端是否可寫入,使用 select 函式來判斷連線要求的完成。
- 如果應用程式使用 WSAAsyncSelect 表示對線上活動感興趣,則應用程式會收到FD_CONNECT通知,指出 連線作業已 順利完成 (,或未) 。
- 如果應用程式使用 WSAEventSelect 來指出對線上活動感興趣,則相關聯的事件物件會發出訊號,指出 連線 作業已順利完成 (,或未) 。
在連線嘗試在非封鎖通訊端上完成之前,相同 通訊端上連線 的所有後續呼叫都會失敗,並出現錯誤碼 WSAEALREADY,並在連線成功完成時 WSAEISCONN 。 由於 Windows Sockets 規格 1.1 版中的模棱兩可,連線已擱置時從 連線 傳回的錯誤碼可能會因實作而有所不同。 因此,不建議應用程式使用多個呼叫來連線以偵測連線完成。 如果這樣做,則必須準備好處理 WSAEINVAL 和 WSAEWOULDBLOCK 錯誤值,就像處理 WSAEALREADY一樣,以確保健全的作業。
如果傳回的錯誤碼指出連線嘗試失敗, (亦即 WSAECONNREFUSED、 WSAENETUNREACH、 WSAETIMEDOUT) 應用程式可以針對相同的通訊端再次呼叫 connect 。
錯誤碼 | 意義 |
---|---|
使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。 | |
網路子系統失敗。 | |
通訊端的本機位址已在使用中,且通訊端未標示為允許與SO_REUSEADDR重複使用位址。 執行系結時,通常會發生此錯誤,但如果系結是 (萬用字元位址,則會延遲到連線函式INADDR_ANY或本機 IP 位址in6addr_any) 。 特定位址必須由 connect 函式隱含系結。 | |
封鎖的 Windows Socket 1.1 呼叫已透過 WSACancelBlockingCall取消。 | |
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。 | |
在指定的通訊端上正在進行非封鎖 連接 呼叫。
注意 為了保留回溯相容性,此錯誤會回報為 WSAEINVAL 至連結到 Winsock.dll 或 Wsock32.dll 的 Windows Sockets 1.1 應用程式。
|
|
遠端位址不是有效的位址 (,例如 INADDR_ANY 或 in6addr_any) 。 | |
指定之系列中的位址無法用於此通訊端。 | |
已強制拒絕連接嘗試。 | |
名稱所指向的 sockaddr結構包含相關聯位址系列或namelen參數的位址格式不正確。 如果name參數所指向且namelen參數中指定長度的sockaddr結構不在使用者位址空間的有效部分,也會傳回此錯誤。 | |
參數 s 是接聽通訊端。 | |
通訊端已 (連線導向通訊端) 。 | |
此時無法透過此主機連接網路。 | |
已嘗試對無法連接的主機進行通訊端作業。 | |
注意 沒有可用的緩衝區空間。 通訊端無法連接。
|
|
s參數中指定的描述項不是通訊端。 | |
嘗試連線逾時而不建立連線。 | |
通訊端標示為非封鎖,且無法立即完成連線。 | |
嘗試將資料包通訊端連線到廣播位址失敗,因為未啟用 setockopt 選項SO_BROADCAST。 |
備註
connect函式可用來建立與指定目的地的連線。 如果通訊端 s是未系結的,系統就會將唯一值指派給本機關聯,而且通訊端會標示為系結。
例如,針對連線導向通訊端 (類型SOCK_STREAM) ,使用 名稱 (通訊端命名空間中的位址來起始對外部主機的作用中連線;如需詳細描述,請參閱 bind 和 sockaddr) 。
當通訊端呼叫成功完成時,通訊端便已準備好傳送和接收資料。 如果 name 參數所指定的結構位址成員填入零, connect 會傳回錯誤 WSAEADDRNOTAVAIL。 任何嘗試重新連線使用中的連線都會失敗,並出現錯誤碼 WSAEISCONN。
針對連線導向的非封鎖通訊端,通常無法立即完成連線。 在這種情況下,此函式會傳回錯誤 WSAEWOULDBLOCK。 不過,作業會繼續進行。
當成功或失敗結果變成已知時,可能會以兩種方式之一回報,視用戶端註冊通知的方式而定。
- 如果用戶端使用 select 函式,則會在 writefds 集合中報告成功,並在 exceptfds 集合中報告失敗。
- 如果用戶端使用 WSAAsyncSelect 或 WSAEventSelect函式,則會以FD_CONNECT宣告通知,而與FD_CONNECT相關聯的錯誤碼表示成功或失敗的特定原因。
如果連線未立即完成,用戶端應該先等候連線完成,再嘗試使用 setockopt設定通訊端選項。 不支援在連線進行時呼叫 setsockopt。
例如,對於無連線通訊端 (輸入 SOCK_DGRAM) ,連線所執行的作業只是建立預設目的地位址,以供後續傳送/ WSASend和recv/ WSARecv呼叫使用。 從指定之目的地位址以外的位址接收的任何資料包都會被捨棄。 如果 名稱 所指定結構的位址成員填入零,通訊端將會中斷連線。 然後,預設遠端位址將會不確定,因此傳送/ WSASend和recv/ WSARecv呼叫將會傳回錯誤碼WSAENOTCONN。 不過,仍然可以使用 sendto/ WSASendTo和recvfrom/ WSARecvFrom。 只要再次呼叫 connect ,即可變更預設目的地,即使通訊端已連線也一樣。 如果 名稱 與上一個 連接不同,則會捨棄任何排入收據的資料包。
針對無連線通訊端, 名稱 可以指出任何有效的位址,包括廣播位址。 不過,若要連線到廣播位址,通訊端必須使用 setsockopt 來啟用 [SO_BROADCAST] 選項。 否則, 連線 將會失敗,並出現錯誤碼 WSAEACCES。
當通訊端之間的連線中斷時,應該捨棄已連接的通訊端,而且應該建立新的通訊端。 當連線通訊端上發生問題時,應用程式必須捨棄通訊端,並再次建立通訊端,才能回到穩定點。
範例程式碼
下列範例示範 如何使用 connect 函式。#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")
int wmain()
{
//----------------------
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup function failed with error: %d\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for connecting to server
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
clientService.sin_port = htons(27015);
//----------------------
// Connect to server.
iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService));
if (iResult == SOCKET_ERROR) {
wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
wprintf(L"Connected to server.\n");
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
WSACleanup();
return 0;
}
如需使用connect函式的另一個範例,請參閱使用 Winsock 消費者入門。
IrDA 通訊端注意事項
- 必須明確包含 Af_irda.h 標頭檔。
- 如果在媒體存取層級偵測到現有的 IrDA 連線,則會傳回 WSAENETDOWN 。
- 如果具有不同位址的裝置作用中連線存在,則會傳回 WSAEADDRINUSE 。
- 如果通訊端已連線或獨佔/多工處理模式變更失敗,則會傳回 WSAEISCONN 。
- 如果通訊端先前系結至本機服務名稱,以使用 系結來接受連入連線,則會傳回 WSAEINVAL 。 請注意,一旦系結通訊端,它就無法用於建立輸出連線。
IrDA 會實作 connect 函式,其格式為 sockaddr_irda。 一般而言,用戶端應用程式會建立具有通訊端功能的通訊端、使用 [IRLMP_ENUMDEVICES通訊端] 選項掃描 IrDA 裝置的鄰近位置、從傳回的清單中選擇裝置、形成位址,然後呼叫 連線。 封鎖和非封鎖語意之間沒有任何差異。
規格需求
最低支援的用戶端 | Windows Vista [傳統型應用程式 |UWP 應用程式] |
最低支援的伺服器 | Windows Server 2003 [傳統型應用程式 |UWP 應用程式] |
目標平台 | Windows |
標頭 | winsock2.h |
程式庫 | Ws2_32.lib |
Dll | Ws2_32.dll |