LPFN_CONNECTEX回呼函式 (mswsock.h)

ConnectEx 函式會建立與指定套接字的連線,並在建立連接后選擇性地傳送數據。 只有連線導向套接字才支援 ConnectEx 函式。

注意 此函式是 Windows Sockets 規格的 Microsoft 特定延伸模組。

 

語法

LPFN_CONNECTEX LpfnConnectex;

BOOL LpfnConnectex(
  [in]           SOCKET s,
  [in]           const sockaddr *name,
  [in]           int namelen,
  [in, optional] PVOID lpSendBuffer,
  [in]           DWORD dwSendDataLength,
  [out]          LPDWORD lpdwBytesSent,
  [in]           LPOVERLAPPED lpOverlapped
)
{...}

參數

[in] s

描述項,識別先前系結的未連接套接字。 如需詳細資訊,請參閱「備註」。

[in] name

的指標
sockaddr 結構,指定要連接的位址。 針對 IPv4,sockaddr 包含位址系列、目的地 IPv4 位址和目的地埠 的AF_INET 。 針對 IPv6,sockaddr 結構包含位址系列、目的地 IPv6 位址、目的地埠,以及可能包含其他 IPv6 流程和範圍標識碼資訊AF_INET6

[in] namelen

name 參數所指向之 sockaddr 結構的長度,以位元組為單位。

[in, optional] lpSendBuffer

建立連接之後要傳送之緩衝區的指標。 這是選擇性參數。 如果在呼叫 ConnectEx之前啟用 TCP_FASTOPEN 選項,則在連線建立期間可能會傳送其中一些數據。

[in] dwSendDataLength

lpSendBuffer 參數所指向數據的長度,以位元組為單位。 當 lpSendBuffer 參數為 NULL 時,會忽略此參數。

[out] lpdwBytesSent

成功傳回時,此參數會指向 DWORD 值,指出建立連接之後所傳送的位元組數目。 傳送的位元組來自 lpSendBuffer 參數所指向的緩衝區。 當 lpSendBuffer 參數為 NULL 時,會忽略此參數。

[in] lpOverlapped

用來處理要求的 OVERLAPPED 結構。 必須指定 lpOverlapped 參數,而且不能是 NULL

傳回值

成功時, ConnectEx 函式會傳回 TRUE。 失敗時,函式會傳回 FALSE。 使用 WSAGetLastError 函式取得擴充錯誤資訊。 如果對 WSAGetLastError 函式的呼叫傳回 ERROR_IO_PENDING,則作業已成功起始且正在進行中。 在這種情況下,當重疊的作業完成時,呼叫仍可能會失敗。

如果傳回的錯誤碼是 WSAECONNREFUSEDWSAENETUNREACHWSAETIMEDOUT,則應用程式可以呼叫 ConnectExWSAConnect,或在相同的套接字上再次 連線

錯誤碼 描述
WSANOTINITIALISED
在使用 ConnectEx 之前,必須先進行成功的 WSAStartup 函式呼叫。
WSAENETDOWN
網路子系統失敗。
WSAEADDRINUSE
套接字的本機位址已在使用中,且套接字未標示為允許使用 SO_REUSEADDR 的位址重複使用。 此錯誤通常會在系結作業期間發生,但如果系結函式是以通配符 (位址呼叫,INADDR_ANY或in6addr_any針對本機 IP 位址指定的) 呼叫系結函式,可能會延遲到 ConnectEx 函式呼叫為止。 特定IP位址必須以隱含方式系結 ConnectEx 函式。
WSAEALREADY
指定的套接字上正在進行非封鎖 連線WSAConnectConnectEx 函數調用。
WSAEADDRNOTAVAIL
遠程位址不是有效的位址,例如ADDR_ANY (ConnectEx 函式僅支援連線導向套接字) 。
WSAEAFNOSUPPORT
指定之系列中的位址無法用於此通訊端。
WSAECONNREFUSED
嘗試連線遭到拒絕。
WSAEFAULT
名稱lpSendBufferlpOverlapped 參數不是使用者位址空間的有效部分,或 namelen 太小。
WSAEINVAL
參數 s 是未系結或接聽套接字。
WSAEISCONN
套接字已連線。
WSAENETUNREACH
此時無法透過此主機連接網路。
WSAEHOSTUNREACH
已嘗試對無法連接的主機進行通訊端作業。
WSAENOBUFS
沒有可用的緩衝區空間;套接字無法連線。
WSAENOTSOCK
描述項不是套接字。
WSAETIMEDOUT
嘗試連線逾時而不建立連線。

備註

ConnectEx 函式會將數個套接字函式結合成單一 API/核心轉換。 當 ConnectEx 函式的呼叫成功完成時,會執行下列作業:

  • 已建立新的連線。
  • 建立連線之後,會傳送選擇性的數據區塊。

針對以 Windows Vista 和更新版本為目標的應用程式,請考慮使用 WSAConnectByListWSAConnectByName 函式,大幅簡化用戶端應用程式設計。

ConnectEx 函式只能與連接導向套接字搭配使用。 傳入 s 參數的套接字必須以套接字類型建立,SOCK_STREAM、SOCK_RDMSOCK_SEQPACKET

lpSendBuffer 參數會指向建立連接之後要傳送的數據緩衝區。 dwSendDataLength 參數會指定要傳送之數據位元組的長度。 應用程式可以使用 ConnectEx,要求使用 ConnectEx 傳送大型數據緩衝區,就像可以使用 SendWSASend 函式一樣。 但強烈建議開發人員使用 ConnectEx 在單一呼叫中傳送大型緩衝區,因為此作業會使用大量的系統記憶體資源,直到傳送整個緩衝區為止。

如果 ConnectEx 函式成功,則已建立連線,而 lpSendBuffer 參數所指向的所有數據都會傳送至 name 參數所指向之 sockaddr 結構中指定的位址。

注意 您必須在運行時間取得 ConnectEx 函式的函式指標,方法是呼叫 WSAIoctl 函式,並指定 SIO_GET_EXTENSION_FUNCTION_POINTER opcode。 傳遞至 WSAIoctl 函式的輸入緩衝區必須包含 WSAID_CONNECTEX,這是全域唯一標識碼 (GUID) ,其值會識別 ConnectEx 延伸模組函式。 成功時, WSAIoctl 函式所傳回的輸出包含 ConnectEx 函式的指標。 WSAID_CONNECTEX GUID 定義於 Mswsock.h 頭檔中。
 

ConnectEx 函式使用重疊的 I/O。 因此, ConnectEx 函式可讓應用程式服務大量的用戶端,且線程相對較少。 相反地, WSAConnect 函式不會使用重疊的 I/O,通常需要在同時收到要求時,個別線程來服務每個連線要求。

注意 當該線程結束時,由指定線程起始的所有 I/O 都會取消。 對於重疊的套接字,如果線程在作業完成之前關閉線程,擱置的異步操作可能會失敗。 如需詳細資訊,請參閱 ExitThread

 

連線導向套接字通常無法立即完成其連線,因此會起始作業,而且函式會立即以ERROR_IO_PENDING或WSA_IO_PENDING錯誤傳回。 當連線作業完成並達到成功或失敗時,會使用 lpOverlapped 中所指出的完成通知機制來報告狀態。 如同所有重疊函數調用,您可以使用事件或完成埠作為完成通知機制。 GetQueuedCompletionStatusGetOverlappedResultWSAGetOverlappedResult 函數的 lpNumberOfBytesTransferred 參數表示要求中傳送的位元組數目。

當 ConnectEx 函式成功完成時,套接字句柄只能傳遞至下列函式:

如果在先前連線的套接字上呼叫 TransmitFile 函式,其中包含TF_DISCONNECT和TF_REUSE_SOCKET旗標,則指定的套接字會傳回至其未連線的狀態,但仍系結。 在這種情況下,套接字的句柄可以傳遞至其 參數中的 ConnectEx 函式,但套接字無法在 AcceptEx 函數調用中重複使用。 同樣地,使用 TransmitFile 函式重複使用的已接受套接字不能用於 ConnectEx 的呼叫中。 請注意,在重複使用的套接字的情況下, ConnectEx 會受限於基礎傳輸的行為。 例如,TCP 套接字可能會受限於 TCP TIME_WAIT狀態,導致 ConnectEx 呼叫延遲。

ConnectEx 函式傳回 TRUE 時,套接字 處於連線套接字的默認狀態。 在套接字上設定SO_UPDATE_CONNECT_CONTEXT之前,套接字不會啟用先前設定的屬性或選項。 使用 setockopt 函式來設定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 );

取得ockopt 函式可以搭配 SO_CONNECT_TIME 套接字選項使用,以檢查 ConnectEx 進行時是否已建立連線。 如果已建立連線,則傳遞至 getsockopt 函式之 optval 參數中傳回的值是套接字已連接的秒數。 如果套接字未連線,傳回 的 optval 參數會包含0xFFFFFFFF。 必須以這種方式檢查連線,以判斷是否已建立連線一段時間,而不傳送任何數據;在這種情況下,建議您終止這類連線。

例如:


//Need to #include <mswsock.h> for SO_CONNECT_TIME

int seconds;
int bytes = sizeof(seconds);
int iResult = 0;

iResult = getsockopt( s, SOL_SOCKET, SO_CONNECT_TIME,
                      (char *)&seconds, (PINT)&bytes );
if ( iResult != NO_ERROR ) {
    printf( "getsockopt(SO_CONNECT_TIME) failed with error: %u\n", 
        WSAGetLastError() );
}
else {
    if (seconds == 0xFFFFFFFF)
        printf("Connection not established yet\n");
    else
       printf("Connection has been established %ld seconds\n",
           seconds);
}

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

如果名稱參數中所指向之 sockaddr 結構的 address 參數全部為零,ConnectEx 會傳回錯誤 WSAEADDRNOTAVAIL。 任何嘗試重新連線使用中的連線都會失敗,並出現錯誤碼 WSAEISCONN

因為任何原因而關閉連線的套接字時,建議捨棄套接字並建立新的套接字。 這是因為基於任何原因,假設當連線套接字上發生問題時,應用程式必須捨棄套接字,並再次建立所需的套接字,才能返回穩定點。

如果使用 TF_REUSE_SOCKET 旗標呼叫 DisconnectEx 函式,則指定的套接字會傳回未連線的狀態,但仍系結。 在這種情況下,套接字的句柄可以傳遞至其 s 參數中的 ConnectEx 函式。

TCP 釋放關閉連線並重複使用其資源的時間間隔,稱為TIME_WAIT狀態或 2MSL 狀態。 在這段期間,相較於建立新的連線,可以重新開啟連線的成本比建立新的連線還要少。

TIME_WAIT行為是在 RFC 793 中指定,這需要 TCP 至少在網路 (MSL) 兩倍的間隔內維護封閉式連線。 當連線釋放時,其套接字組和用於套接字的內部資源可用來支援另一個連線。

Windows TCP 會在連線關閉之後還原為TIME_WAIT狀態。 處於TIME_WAIT狀態時,無法重複使用套接字組。 TIME_WAIT期間可藉由修改下列 DWORD 登錄設定來設定,以秒為單位表示TIME_WAIT期間。

\ HKEY_LOCAL_MACHINE系統\CurrentControlSet\服務\TCPIP\參數\TcpTimedWaitDelay

根據預設,MSL 會定義為120秒。 TcpTimedWaitDelay 登錄設定預設為值 240 秒,代表 120 秒或 4 分鐘的最大區段存留期 2 倍。 不過,您可以使用這個項目來自定義間隔。

減少這個專案的值可讓 TCP 更快釋放關閉的連線,為新的連線提供更多資源。 不過,如果此值太低,TCP 可能會在聯機完成之前釋放連線資源,要求伺服器使用其他資源重新建立連線。

此登錄設定可以從 0 設定為 300 秒。

Windows Phone 8:Windows Phone 8 和更新版本上的 Windows Phone Store 應用程式支援此函式。

Windows 8.1Windows Server 2012 R2:Windows 市集應用程式支援 Windows 8.1、Windows Server 2012 R2 和更新版本。

規格需求

需求
最低支援的用戶端 Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 mswsock.h

另請參閱

AcceptEx

DisconnectEx

ExitThread

GetOverlappedResult

GetQueuedCompletionStatus

重疊

ReadFile

TransmitFile

WSAConnect

WSAConnectByList

WSAConnectByName

WSAGetLastError

WSAIoctl

WSARecv

WSASend

WSAStartup

Winsock 函式

Winsock 參考

WriteFile

bind

closesocket

connect

getsockopt

recv

send

sendto

setsockopt

sockaddr