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 版中的模棱兩可,連線已擱置時從 連線 傳回的錯誤碼可能會因實作而有所不同。 因此,不建議應用程式使用多個呼叫來連線以偵測連線完成。 如果這樣做,則必須準備好處理 WSAEINVALWSAEWOULDBLOCK 錯誤值,就像處理 WSAEALREADY一樣,以確保健全的作業。

如果傳回的錯誤碼指出連線嘗試失敗, (亦即 WSAECONNREFUSEDWSAENETUNREACHWSAETIMEDOUT) 應用程式可以針對相同的通訊端再次呼叫 connect

錯誤碼 意義
WSANOTINITIALISED
使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。
WSAENETDOWN
網路子系統失敗。
WSAEADDRINUSE
通訊端的本機位址已在使用中,且通訊端未標示為允許與SO_REUSEADDR重複使用位址。 執行系結時,通常會發生此錯誤,但如果系是 (萬用字元位址,則會延遲到連線函式INADDR_ANY或本機 IP 位址in6addr_any) 。 特定位址必須由 connect 函式隱含系結。
WSAEINTR
封鎖的 Windows Socket 1.1 呼叫已透過 WSACancelBlockingCall取消。
WSAEINPROGRESS
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。
WSAEALREADY
在指定的通訊端上正在進行非封鎖 連接 呼叫。
注意 為了保留回溯相容性,此錯誤會回報為 WSAEINVAL 至連結到 Winsock.dll 或 Wsock32.dll 的 Windows Sockets 1.1 應用程式。
 
WSAEADDRNOTAVAIL
遠端位址不是有效的位址 (,例如 INADDR_ANYin6addr_any)
WSAEAFNOSUPPORT
指定之系列中的位址無法用於此通訊端。
WSAECONNREFUSED
已強制拒絕連接嘗試。
WSAEFAULT
名稱所指向的 sockaddr結構包含相關聯位址系列或namelen參數的位址格式不正確。 如果name參數所指向且namelen參數中指定長度的sockaddr結構不在使用者位址空間的有效部分,也會傳回此錯誤。
WSAEINVAL
參數 s 是接聽通訊端。
WSAEISCONN
通訊端已 (連線導向通訊端) 。
WSAENETUNREACH
此時無法透過此主機連接網路。
WSAEHOSTUNREACH
已嘗試對無法連接的主機進行通訊端作業。
WSAENOBUFS
注意 沒有可用的緩衝區空間。 通訊端無法連接。
 
WSAENOTSOCK
s參數中指定的描述項不是通訊端。
WSAETIMEDOUT
嘗試連線逾時而不建立連線。
WSAEWOULDBLOCK
通訊端標示為非封鎖,且無法立即完成連線。
WSAEACCES
嘗試將資料包通訊端連線到廣播位址失敗,因為未啟用 setockopt 選項SO_BROADCAST。

備註

connect函式可用來建立與指定目的地的連線。 如果通訊端 s是未系結的,系統就會將唯一值指派給本機關聯,而且通訊端會標示為系結。

例如,針對連線導向通訊端 (類型SOCK_STREAM) ,使用 名稱 (通訊端命名空間中的位址來起始對外部主機的作用中連線;如需詳細描述,請參閱 bindsockaddr) 。

注意 如果開啟通訊端,就會進行 setockopt 呼叫,然後進行 sendto 呼叫,Windows Sockets 會執行隱含 系結 函式呼叫。

 

當通訊端呼叫成功完成時,通訊端便已準備好傳送和接收資料。 如果 name 參數所指定的結構位址成員填入零, connect 會傳回錯誤 WSAEADDRNOTAVAIL。 任何嘗試重新連線使用中的連線都會失敗,並出現錯誤碼 WSAEISCONN

針對連線導向的非封鎖通訊端,通常無法立即完成連線。 在這種情況下,此函式會傳回錯誤 WSAEWOULDBLOCK。 不過,作業會繼續進行。

當成功或失敗結果變成已知時,可能會以兩種方式之一回報,視用戶端註冊通知的方式而定。

  • 如果用戶端使用 select 函式,則會在 writefds 集合中報告成功,並在 exceptfds 集合中報告失敗。
  • 如果用戶端使用 WSAAsyncSelectWSAEventSelect函式,則會以FD_CONNECT宣告通知,而與FD_CONNECT相關聯的錯誤碼表示成功或失敗的特定原因。

如果連線未立即完成,用戶端應該先等候連線完成,再嘗試使用 setockopt設定通訊端選項。 不支援在連線進行時呼叫 setsockopt。

例如,對於無連線通訊端 (輸入 SOCK_DGRAM) ,連線所執行的作業只是建立預設目的地位址,以供後續傳送/ WSASendrecv/ WSARecv呼叫使用。 從指定之目的地位址以外的位址接收的任何資料包都會被捨棄。 如果 名稱 所指定結構的位址成員填入零,通訊端將會中斷連線。 然後,預設遠端位址將會不確定,因此傳送/ WSASendrecv/ WSARecv呼叫將會傳回錯誤碼WSAENOTCONN。 不過,仍然可以使用 sendto/ WSASendTorecvfrom/ WSARecvFrom。 只要再次呼叫 connect ,即可變更預設目的地,即使通訊端已連線也一樣。 如果 名稱 與上一個 連接不同,則會捨棄任何排入收據的資料包。

針對無連線通訊端, 名稱 可以指出任何有效的位址,包括廣播位址。 不過,若要連線到廣播位址,通訊端必須使用 setsockopt 來啟用 [SO_BROADCAST] 選項。 否則, 連線 將會失敗,並出現錯誤碼 WSAEACCES

當通訊端之間的連線中斷時,應該捨棄已連接的通訊端,而且應該建立新的通訊端。 當連線通訊端上發生問題時,應用程式必須捨棄通訊端,並再次建立通訊端,才能回到穩定點。

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

範例程式碼

下列範例示範 如何使用 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

另請參閱

WSAAsyncSelect

WSAConnect

ConnectEx

Winsock 函式

Winsock 參考

接受

bind

getsockname

select

sockaddr

socket