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旗標,則會將指定的通訊端傳回至未連線的狀態,但仍系結。 在這種情況下,通訊端的控制碼可以在其s參數中傳遞至ConnectEx函式,但通訊端無法在AcceptEx函式呼叫中重複使用。 同樣地,使用 TransmitFile 函式重複使用的已接受通訊端不能用於 ConnectEx的呼叫中。 請注意,在重複使用的通訊端的情況下, ConnectEx 會受限於基礎傳輸的行為。 例如,TCP 通訊端可能會受限於 TCP TIME_WAIT 狀態,導致 ConnectEx 呼叫延遲。

ConnectEx 函式傳回 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 );

getsockopt函式可以與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 會執行隱含 系結 函式呼叫。
 

如果name參數中所指向之 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 Windows Phone 8 和更新版本上的市集應用程式支援此函式。

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