LPFN_WSARECVMSG回呼函式 (mswsock.h)
LPFN_WSARECVMSG 是函式指標類型。 您可以在應用程式中實作相符的 WSARecvMsg 回呼函式。 系統會使用您的回呼函式,透過連線的套接字,將記憶體內部資料或檔案數據傳輸給您。
您的 WSARecvMsg 回呼函式會從連線和未連線的套接字接收具有訊息的輔助數據/控制資訊。
注意
此函式是 Windows Sockets 規格的 Microsoft 特定延伸模組。
語法
LPFN_WSARECVMSG LpfnWsarecvmsg;
INT LpfnWsarecvmsg(
SOCKET s,
LPWSAMSG lpMsg,
LPDWORD lpdwNumberOfBytesRecvd,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
{...}
參數
s
類型:_In_ SOCKET
識別套接字的描述項。
lpMsg
類型:_Inout_ LPWSAMSG
以 msghdr 結構的 Posix.1g 規格為基礎的 WSAMSG 結構的指標。
lpdwNumberOfBytesRecvd
類型:_Out_opt_ LPDWORD
如果 WSARecvMsg 作業立即完成,則為 DWORD 指標,其中包含此呼叫所接收的位元組數目。
若要避免可能錯誤的結果,如果 lpOverlapped 參數不是 NULL,請傳遞此參數的 NULL。 只有當 lpOverlapped 參數不是 NULL 時,此參數才能為 NULL。
lpOverlapped
類型:_Inout_opt_ LPWSAOVERLAPPED
WSAOVERLAPPED 結構的指標。 忽略非重疊結構。
lpCompletionRoutine
類型:_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
完成例程的指標,會在接收作業完成時呼叫。 忽略非重疊結構。
傳回值
如果沒有發生錯誤,而且接收作業已立即完成, WSARecvMsg 會傳回零。 在此情況下,一旦呼叫線程處於可警示狀態,就會排程完成例程來呼叫。 否則,會傳回SOCKET_ERROR的值,而且可以呼叫 WSAGetLastError 來擷取特定的錯誤碼。 錯誤碼 WSA_IO_PENDING 指出重疊的作業已成功起始,且稍後將會指出完成。
任何其他錯誤碼表示作業未成功起始,而且如果要求重疊的作業,則不會發生任何完成指示。
錯誤碼 | 意義 |
---|---|
WSAECONNRESET | 針對 UDP 數據報套接字,此錯誤會指出先前的傳送作業導致 ICMP「無法連線埠」訊息。 |
WSAEFAULT | lpBuffers、lpFlags、lpFrom、lpNumberOfBytesRecvd、lpFromlen、lpOverlapped 或 lpCompletionRoutine 參數並未完全包含在使用者地址空間的有效部分:lpFrom 緩衝區太小而無法容納對等位址。 如果 lpMsg 參數所指向的 WSAMSG 結構名稱成員是 NULL 指標,且 WSAMSG 結構的 namelen 成員未設定為零,也會傳回此錯誤。 如果 lpMsg 參數所指向之 WSAMSG 結構的 Control.buf 成員是 NULL 指標,且 WSAMSG 結構的 Control.len 成員未設定為零,也會傳回此錯誤。 |
WSAEINPROGRESS | 封鎖的 Windows Sockets 1.1 呼叫正在進行中,或者服務提供者仍在處理回呼函式。 |
WSAEINTR | 封鎖的 Windows Socket 1.1 呼叫已透過 WSACancelBlockingCall 取消。 |
WSAEINVAL | 套接字尚未系結 (系 結,例如) 。 |
WSAEMSGSIZE | 訊息太大而無法放入指定的緩衝區中,而且 (只) 未放入緩衝區之訊息的任何尾端部分已捨棄。 |
WSAENETDOWN | 網路子系統失敗。 |
WSAENETRESET | 如果是資料包通訊端,此錯誤表示已超過存留時間。 |
WSAENOTCONN | 套接字未連線 (連線導向套接字) 。 |
WSAETIMEDOUT | 套接字逾時。如果套接字有使用 SO_RCVTIMEO 套接字選項指定的等候逾時,且超過逾時,就會傳回此錯誤。 |
WSAEOPNOTSUPP | 不支援套接字作業。 如果 lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員包含非數據報套接字上的MSG_PEEK控件旗標,就會傳回此錯誤。 |
WSAEWOULDBLOCK | Windows NT: 重疊的套接字:有太多未處理的重疊 I/O 要求。 非重疊的套接字:套接字標示為非封鎖,且無法立即完成接收作業。 |
WSANOTINITIALISED | 使用此函式之前,必須先進行成功的 WSAStartup 呼叫。 |
WSA_IO_PENDING | 已成功起始重疊的作業,稍後將會指出完成。 |
WSA_OPERATION_ABORTED | 由於套接字關閉,已取消重疊的作業。 |
備註
WSARecvMsg 函式可用來取代 WSARecv 和 WSARecvFrom 函式,以接收連線和未連線套接字的數據和選擇性控制資訊。 WSARecvMsg 函式只能與數據報和原始套接字搭配使用。 必須開啟 s 參數中的套接字描述元,並將套接字類型設定為 SOCK_DGRAM 或 SOCK_RAW。
注意您必須在運行時間取得 WSARecvMsg 函式的函式指標,方法是呼叫具有指定之 SIO_GET_EXTENSION_FUNCTION_POINTER opcode 的 WSAIoctl 函式。 傳遞至 WSAIoctl 函式的輸入緩衝區必須包含 WSAID_WSARECVMSG,這是全域唯一標識碼 (GUID) ,其值可識別 WSARecvMsg 延伸模組函式。 成功時, WSAIoctl 函式所傳回的輸出包含 WSARecvMsg 函式的指標。 WSAID_WSARECVMSG GUID 定義於 Mswsock.h 頭檔中。
lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員只能包含輸入上的MSG_PEEK控件旗標。
重疊套接字是使用已設定WSA_FLAG_OVERLAPPED旗標的WSASocket 函數調用所建立。 對於重疊的套接字,除非 lpOverlapped 和 lpCompletionRoutine 參數都是 NULL,否則接收資訊會使用重疊的 I/O。 當 lpOverlapped 和 lpCompletionRoutine 參數都是 NULL 時,套接字會被視為非重疊的套接字。
完成指示會與重疊的套接字一起發生。 傳輸取用緩衝區或緩衝區之後,就會觸發完成例程或設定事件物件。 如果作業未立即完成,則會透過完成例程或呼叫 WSAGetOverlappedResult 函式來擷取最終完成狀態。
對於重疊的套接字, WSARecvMsg 用來張貼一或多個傳入數據的緩衝區,當傳入數據變成可用時,應用程式指定的完成指示之後,就會 (叫用完成例程或事件物件) 設定。 如果作業未立即完成,則會透過完成例程或 WSAGetOverlappedResult 函式擷取最終完成狀態。
針對非重迭套接字,封鎖語意與標準 recv 函式的語意相同,並忽略 lpOverlapped 和 lpCompletionRoutine 參數。 傳輸已接收和緩衝處理的任何數據,都會複製到指定的用戶緩衝區。 如果封鎖套接字目前未收到任何數據並受到傳輸緩衝,則呼叫將會封鎖,直到收到數據為止。 Windows Sockets 2 未定義此函式的任何標準封鎖逾時機制。 對於做為位元組數據流通訊協定的通訊協定,堆疊會嘗試盡可能根據可用的緩衝區空間和接收的數據量傳回數據量。 不過,收到單一位元組就足以解除封鎖呼叫端。 不保證會傳回超過單一位元組。 對於做為訊息導向的通訊協定,需要完整訊息才能解除封鎖呼叫端。
注意SO_RCVTIMEO套接字選項僅適用於封鎖套接字。
緩衝區會填入它們出現在 lpMsg 參數所指向之 WSAMSG 結構的 lpBuffers 成員所指向的數位中的順序,並封裝緩衝區,這樣就不會建立任何漏洞。
如果此函式是以重疊的方式完成,在從這個呼叫傳回之前,Winsock 服務提供者必須負責擷取此 WSABUF 結構。 這可讓應用程式建置由 lpMsg 參數所指向之 WSAMSG 結構的 lpBuffers 成員所指向的堆疊型 WSABUF 陣列。
對於訊息導向套接字 (SOCK_DGRAM或SOCK_RAW) 的套接字類型,傳入訊息會放在緩衝區中,最多可達緩衝區的大小總計,而重疊套接字的完成指示就會發生。 如果訊息大於緩衝區,則緩衝區會填入訊息的第一個部分,並遺失多餘的數據, 而 WSARecvMsg 會產生錯誤 WSAEMSGSIZE。
在類型為 SOCK_DGRAM 或 SOCK_RAW 的 IPv4 套接字上啟用IP_PKTINFO套接字選項時,WSARecvMsg 函式會在 lpMsg 參數所指向的 WSAMSG 結構中傳回封包資訊。 傳回 WSAMSG 結構中的其中一個控制資料物件會包含用來儲存已接收封包地址資訊的 in_pktinfo 結構。
對於透過 IPv4 接收的數據報,收到的 WSAMSG 結構的 Control 成員將包含包含 WSACMSGHDR 結構的 WSABUF 結構。 此 WSACMSGHDR 結構的cmsg_level成員會包含IPPROTO_IP、此結構的cmsg_type成員會包含IP_PKTINFO,而cmsg_data成員會包含用來儲存已接收 IPv4 封包地址資訊的in_pktinfo結構。 in_pktinfo 結構中的 IPv4 位址是接收封包的來源 IPv4 位址。
在類型為 SOCK_DGRAM 或 SOCK_RAW 的 IPv6 套接字上啟用IPV6_PKTINFO套接字選項時,WSARecvMsg 函式會在 lpMsg 參數所指向的 WSAMSG 結構中傳回封包資訊。 傳回 WSAMSG 結構中的其中一個控制資料物件會包含用來儲存已接收封包地址資訊的 in6_pktinfo 結構。
對於透過 IPv6 接收的數據報,收到的 WSAMSG 結構的 Control 成員將包含包含 WSACMSGHDR 結構的 WSABUF 結構。 此 WSACMSGHDR 結構的cmsg_level成員會包含IPPROTO_IPV6,此結構的cmsg_type成員會包含IPV6_PKTINFO,而cmsg_data成員會包含用來儲存已接收 IPv6 封包地址資訊的in6_pktinfo結構。 in6_pktinfo 結構中的 IPv6 位址是接收封包的來源 IPv6 位址。
如果是雙堆棧數據報套接字,如果應用程式要求 WSARecvMsg 函式在 WSAMSG 結構中傳回透過 IPv4 接收的數據報封包資訊,則必須在套接字上 將IP_PKTINFO 套接字選項設定為 true。 如果套接字上只有 IPV6_PKTINFO 選項設定為 true,則會針對透過 IPv6 接收的數據報提供封包資訊,但可能無法針對透過 IPv4 接收的數據報提供。
請注意, Ws2ipdef.h 頭文件會自動包含在 Ws2tcpip.h 中,不應直接使用。
注意 當該線程結束時,由指定線程起始的所有 I/O 都會取消。 對於重疊的套接字,如果線程在作業完成之前關閉線程,擱置的異步操作可能會失敗。 如需詳細資訊,請參閱 ExitThread。
Windows Phone 8:Windows Phone 8 和更新版本上的 Windows Phone Store 應用程式支援此函式。
Windows 8.1和 Windows Server 2012 R2:Windows 市集應用程式支援 Windows 8.1、Windows Server 2012 R2 和更新版本。
dwFlags
在輸入時,lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員可用來影響函式調用的行為,超過針對相關聯套接字指定的套接字選項。 也就是說,此函式的語意取決於套接字選項和 WSAMSG 結構的 dwFlags 成員。 lpMsg 參數所指向 WSAMSG 結構之 dwFlags 成員的唯一可能輸入值是MSG_PEEK。
值 | 意義 |
---|---|
MSG_PEEK | 預覽 傳入的數據。 數據會複製到緩衝區,但不會從輸入佇列中移除。 此旗標僅適用於非重疊的套接字。 |
輸入上 dwFlags 成員的可能值定義在 Winsock2.h 頭檔中。
輸出時,lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員可能會傳回下列任何值的組合。
值 | 意義 |
---|---|
MSG_BCAST | 數據報是以連結層廣播的形式接收,或是具有廣播位址的目的地IP位址。 |
MSG_CTRUNC | 已截斷控件 () 數據。 控件數據比進程配置的空間還多。 |
MSG_MCAST | 數據報是以多播位址的目的地 IP 位址接收。 |
MSG_TRUNC | 數據報已截斷。 數據比進程配置的空間還多。 |
在針對 Windows Vista 和更新版本發行的 Microsoft Windows 軟體開發套件 (SDK) 上,頭檔的組織已變更,而且輸出上 dwFlags 成員的可能值定義在 Ws2def.h 頭檔中,此檔由 Winsock2.h 頭文件自動包含。
在 Windows Server 2003 和更早版本的 Platform Software Development Kit (SDK) 版本上,輸出上 dwFlags 成員的可能值定義在 Mswsock.h 頭檔中。
注意 發出封鎖的 Winsock 呼叫,例如 WSARecvMsg ,並將 lpOverlapped 參數設定為 NULL 時,Winsock 可能需要等候網路事件,才能完成呼叫。 Winsock 會在這種情況中執行可警示的等候,而異步過程調用 (APC) 排程在同一個線程上,可能會中斷。 在 APC 內發出另一個封鎖 Winsock 呼叫,中斷相同線程上持續封鎖 Winsock 呼叫會導致未定義的行為,而且永遠不會由 Winsock 客戶端嘗試。
重疊的套接字 I/O
如果重疊的作業立即完成, WSARecvMsg 會傳回值為零,且 lpNumberOfBytesRecvd 參數會更新已接收的位元組數目,而且 也會更新 lpFlags 參數所指示的旗標位。 如果重疊的作業已成功起始,且稍後將會完成, WSARecvMsg 會傳回 SOCKET_ERROR ,並指出錯誤碼 WSA_IO_PENDING。 在此情況下,不會更新 lpNumberOfBytesRecvd 。 當重疊的作業完成時,如果指定) ,或透過WSAGetOverlappedResult 中的 lxmlTransfer 參數,則會透過完成例程中的 cbTransfer 參數來指出傳輸的數據量 (。 旗標值是藉由檢查 WSAGetOverlappedResult 的 lpdwFlags 參數來取得。
您可以從先前 WSARecv、WSARecvFrom、WSARecvFrom、WSARecvMsg、WSASend、WSASendMsg 或 WSASendTo 函式的完成例程內呼叫 WSARecvMsg 函式。 針對指定的套接字,I/O 完成例程不會巢狀化。 這可讓時間敏感的數據傳輸完全發生在先佔式內容內。
lpOverlapped 參數在重迭作業期間必須有效。 如果同時未完成多個 I/O 作業,每個作業都必須參考個別 的 WSAOVERLAPPED 結構。
如果 lpCompletionRoutine 參數為 NULL,當重疊的作業包含有效的事件物件句柄時,就會發出 lpOverlapped 的 hEvent 參數訊號。 應用程式可以使用 WSAWaitForMultipleEvents 或 WSAGetOverlappedResult 來等候或輪詢事件物件。
如果 lpCompletionRoutine 不是 NULL, 則會忽略 hEvent 參數,並可供應用程式用來將內容資訊傳遞至完成例程。 呼叫端,將非 NULLlpCompletionRoutine 和更新版本針對相同的重疊 I/O 要求呼叫 WSAGetOverlappedResult,可能不會將該 WSAGetOverlappedResult 調用的 fWait 參數設定為 TRUE。 在此情況下, 未定義 hEvent 參數的使用方式,而嘗試等候 hEvent 參數會產生無法預測的結果。
完成例程遵循與 Windows 檔案 I/O 完成例程規定相同的規則。 在線程處於可警示的等候狀態之前,將不會叫用完成例程,例如當叫用 fAlertable 參數設為 TRUE 的函式 WSAWaitForMultipleEvents 時,才會叫用完成例程。
完成例程的原型如下所示:
void CALLBACK CompletionRoutine(
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
);
CompletionRoutine 是應用程式定義或連結庫定義函數名稱的佔位元。 dwError 參數會指定重迭作業的完成狀態,如 lpOverlapped 參數所指出。 cbTransferred 參數會指定收到的位元組數目。 dwFlags 參數包含如果接收作業已立即完成,也會在 lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員中傳回的資訊。 CompletionRoutine 函式不會傳回值。
從此函式傳回允許叫用此套接字的另一個擱置完成例程。 使用 WSAWaitForMultipleEvents 時,所有等候完成例程都會在可警示線程的等候符合 WSA_IO_COMPLETION的傳回碼之前呼叫。 您可以依任何順序呼叫完成例程,不一定以相同順序呼叫重疊作業。 不過,保證已張貼的緩衝區會以指定的順序填入。
如果您使用 I/O 完成埠,請注意對 WSARecvMsg 進行的呼叫順序也是緩衝區填入的順序。 WSARecvMsg 函式不應該同時從不同的線程在相同的套接字上呼叫,因為它可能會導致無法預期的緩衝區順序。
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | Windows 10 組建 20348 |
最低支援的伺服器 | Windows 10 組建 20348 |
標頭 | mswsock.h |