LPWSPRECV 回呼函式 (ws2spi.h)

LPWSPRecv 函式會在套接字上接收數據。

語法

LPWSPRECV Lpwsprecv;

int Lpwsprecv(
  [in]         SOCKET s,
  \[in\, out\] LPWSABUF lpBuffers,
  [in]         DWORD dwBufferCount,
  [out]        LPDWORD lpNumberOfBytesRecvd,
  \[in\, out\] LPDWORD lpFlags,
  [in]         LPWSAOVERLAPPED lpOverlapped,
  [in]         LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  [in]         LPWSATHREADID lpThreadId,
  [out]        LPINT lpErrno
)
{...}

參數

[in] s

識別已連線套接字的描述項。

\\[in\\, out\\] lpBuffers

WSABUF 結構的陣列指標。 每個 WSABUF 結構都包含緩衝區的指標和緩衝區的長度,以位元組為單位。

[in] dwBufferCount

lpBuffers 陣列中的 WSABUF 結構數目。

[out] lpNumberOfBytesRecvd

這個呼叫所接收位元組數目的指標。

\\[in\\, out\\] lpFlags

旗標的指標,指定呼叫的進行方式。

[in] lpOverlapped

非重疊結構) 忽略 WSAOverlapped 結構的指標 (。

[in] lpCompletionRoutine

類型:_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

當接收作業已完成時呼叫的完成例程指標, (忽略非重疊結構) 。

[in] lpThreadId

提供者後續呼叫 WPUQueueApc 時要使用的 WSATHREADID 結構的指標。 提供者應該儲存參考的 WSATHREADID 結構, (在 WPUQueueApc 函式傳回之後,才儲存相同) 的指標。

[out] lpErrno

錯誤碼的指標。

傳回值

如果沒有發生錯誤,而且接收作業已立即完成, LPWSPRecv 會傳回零。 請注意,在此情況下,如果指定完成例程,則已經排入佇列。 否則會傳回SOCKET_ERROR的值,並在 lpErrno 中提供特定的錯誤碼。 錯誤碼WSA_IO_PENDING指出重疊的作業已成功起始,且稍後將會指出完成。 任何其他錯誤碼都表示未起始重疊的作業,也不會發生任何完成指示。

錯誤碼 意義
WSAENETDOWN
網路子系統失敗。
WSAENOTCONN
通訊端未連線。
WSAEINTR
(封鎖) 呼叫已透過 LPWSPCancelBlockingCall 取消。
WSAEINPROGRESS
封鎖 Windows Sockets 呼叫正在進行中,或服務提供者仍在處理回呼函式。
WSAENETRESET
線上已中斷,因為持續運作活動偵測作業正在進行時失敗。
WSAEFAULT
lpBuffers 參數未完全包含在用戶位址空間的有效部分中。
WSAENOTSOCK
描述項不是套接字。
WSAEOPNOTSUPP
已指定MSG_OOB,但套接字不是數據流樣式,例如類型SOCK_STREAM、與此套接字相關聯的通訊網域不支援 OOB 數據,或套接字是單向的,而且僅支援傳送作業。
WSAESHUTDOWN
套接字已關閉;在叫用 LPWSPShutdown 之後,無法在套接字上透過 LPWSPRecv 接收,以及如何將 設定為 SD_RECEIVE 或 SD_BOTH。
WSAEWOULDBLOCK
Windows NT:重疊的套接字:有太多未處理的重疊 I/O 要求。 未重疊的套接字:套接字標示為非封鎖,而且無法立即完成接收作業。
WSAEMSGSIZE
訊息太大而無法放入指定的緩衝區,而且 (不可靠的通訊協定,只會) 未放入緩衝區之訊息的任何尾端部分遭到捨棄。
WSAEINVAL
例如,套接字尚未系結 (,使用 LPWSPBind) ,或未使用重迭旗標建立套接字。
WSAECONNABORTED
虛擬線路因逾時或其他失敗而終止。
WSAECONNRESET
虛擬線路已由遠端重設。
WSAEDISCON
套接字是訊息導向,且虛擬線路已由遠端正常關閉。
WSA_IO_PENDING
已成功起始重疊的作業,且稍後將會指出完成。
WSA_OPERATION_ABORTED
因為套接字關閉,所以已取消重疊的作業。

備註

LPWSPRecv 用於連接的套接字或 s 參數所指定的系結無連接套接字,並且用來讀取傳入數據。 必須知道套接字的本機位址。 這可以透過 LPWSPBind 明確完成,或透過 LPWSPAcceptLPWSPConnectLPWSPSendToLPWSPJoinLeaf 明確完成。

對於已連線、無連線的套接字,此函式會限制接受接收訊息的位址。 函式只會從連接中指定的遠端位址傳回訊息。 其他地址的訊息 (以無訊息方式) 捨棄。

對於重疊的套接字 ,LPWSPRecv 會用來張貼一或多個緩衝區,當傳入數據變成可用時,就會在其中放置傳入數據的緩衝區,之後,Windows Sockets SPI 用戶端指定的完成指示 (叫用事件物件或事件物件) 設定。 如果作業未立即完成,則會透過完成例程或 LPWSPGetOverlappedResult 擷取最終完成狀態。

如果 lpOverlappedlpCompletionRoutine 都是 null,此函式中的套接字將會被視為非重疊套接字。

若為非重疊套接字,則會忽略 lpOverlappedlpCompletionRoutinelpThreadId 參數。 傳輸已接收和緩衝處理的任何數據,都會複製到提供的用戶緩衝區。 對於目前未接收和緩衝傳輸之數據的封鎖套接字案例,呼叫會封鎖直到收到數據為止。 Windows Sockets 2 不會定義此函式的任何標準封鎖逾時機制。 對於做為位元組數據流通訊協定的通訊協定,堆疊會嘗試盡可能根據提供的緩衝區空間和已接收的數據量傳回數據量。 不過,單一位元組的收據就足以解除封鎖呼叫端。 不保證會傳回多個字節。 對於作為訊息導向的通訊協定,需要完整訊息才能解除封鎖呼叫端。

通訊協定是否做為位元組數據流,是由XP1_MESSAGE_ORIENTED及其 WSAPROTOCOL_INFO 結構中的XP1_PSEUDO_STREAM設定,以及傳入此函式的MSG_PARTIAL旗標設定, (支援) 的通訊協議來決定。 下表摘要說明相關組合, (星號 (*) 表示此位的設定在此案例中並不重要) 。

XP1_MESSAGE_ORIENTED XP1_PSEUDO_STREAM MSG_PARTIAL 做為
未設定 * * 位元組數據流
* set * 位元組數據流
set 未設定 set 位元組數據流
set 未設定 未設定 訊息導向

提供的緩衝區會依照它們出現在 lpBuffers 所指向的數位列中的順序填入,而緩衝區會封裝在一起,因此不會建立任何漏洞。

由 lpBuffers 參數指向的 WSABUF 結構陣列是暫時性的。 如果此作業以重疊的方式完成,服務提供者必須負責先擷取 WSABUF 結構的這個指標數位,再從這個呼叫傳回。 這可讓 Windows Sockets SPI 用戶端建置堆疊式 WSABUF 陣列。

例如,針對位元組數據流樣式套接字 (輸入 SOCK_STREAM) ,傳入的數據會放在緩衝區中,直到緩衝區填滿、連接已關閉或內部緩衝的數據耗盡為止。 不論傳入的數據是否填滿所有緩衝區,重疊套接字都會發生完成指示。 例如,針對訊息導向套接字 (類型SOCK_DGRAM) ,傳入訊息會放在提供的緩衝區中,最多為提供的緩衝區大小總計,而重疊套接字的完成指示就會發生。 如果訊息大於提供的緩衝區,則緩衝區會填入訊息的第一個部分。 如果服務提供者支援MSG_PARTIAL功能,MSG_PARTIAL旗標會在 lpFlags 中設定,後續的接收作業 (s) 可用來擷取訊息的其餘部分。 如果不支援MSG_PARTIAL,但通訊協定可靠, LPWSPRecv 會產生錯誤 WSAEMSGSIZE ,並使用較大的緩衝區後續接收作業可用來擷取整個訊息。 否則, (,通訊協定不可靠且不支援MSG_PARTIAL) 、多餘的數據遺失, 而 LPWSPRecv 會產生錯誤 WSAEMSGSIZE。

針對連線導向套接字, LPWSPRecv 可以透過兩種方式之一來指出虛擬線路的正常終止,視套接字是位元組資料流或訊息導向而定。 對於位元組數據流,零個已讀取的位元組表示正常關閉,而且不會再讀取任何位元組。 對於訊息導向套接字,其中通常允許零位元組訊息,則會使用 WSAEDISCON 的傳回錯誤碼來表示正常關閉。 在任何情況下, WSAECONNRESET 的傳回錯誤碼都表示已中止關閉。

lpFlags 參數可用來影響函式調用的行為,超過為相關聯套接字指定的選項。 也就是說,此函式的語意取決於套接字選項和 lpFlags 參數。 後者是使用位 OR 運算元搭配下列任何值來建構。

意義
MSG_PEEK 查看傳入的數據。 數據會複製到緩衝區,但不會從輸入佇列中移除。 此旗標僅適用於未重疊的套接字。
MSG_OOB 處理頻外 (OOB) 數據。
MSG_PARTIAL 此旗標僅適用於訊息導向套接字。 輸出時,表示提供的數據是傳送者所傳輸之訊息的一部分。 後續接收作業中會提供訊息的其餘部分。 已清除MSG_PARTIAL旗標的後續接收作業表示發件者的訊息結束。 做為輸入參數,MSG_PARTIAL表示即使服務提供者只收到部分訊息,接收作業也應該完成。

如果重疊的作業立即完成, 則 LPWSPRecv 會傳回值為零,且 lpNumberOfBytesRecvd 參數會更新已接收的位元組數目,而且 也會更新 lpFlags 參數所指向的旗標位。 如果重疊的作業已成功起始,且稍後將會完成, LPWSPRecv 會傳回SOCKET_ERROR,並指出錯誤碼 WSA_IO_PENDING。 在此情況下,不會更新 lpNumberOfBytesRecvdlpFlags 。 當重疊的作業完成時,傳送的數據量會透過完成例程中的 cbTransferred 參數指出 (,如果指定) ,或透過 LPWSPGetOverlappedResult 中的 lxmlTransfer 參數,則表示。 旗標值是透過完成例程的 dwFlags 參數取得,或是檢查 WSAGetOverlappedResultlpdwFlags 參數來取得。

提供者必須允許從先前 LPWSPRecv、LPWSPRecvFromLPWSPSend 或 LPWSPSendTo 函式的完成例程內呼叫此函式。 不過,對於指定的套接字,I/O 完成例程不能巢狀化。 這可讓時間敏感的數據傳輸完全發生在先佔式內容內。

lpOverlapped 參數在重迭作業期間必須有效。 如果同時未完成多個 I/O 作業,每個作業都必須參考個別的重疊結構。 WSAOverlapped 結構是在自己的參考頁面中定義。

如果 lpCompletionRoutine 參數為 Null,當重疊的作業包含有效的事件物件句柄時,服務提供者會發出 lpOverlappedhEvent 成員訊號。 Windows Sockets SPI 用戶端可以使用 LPWSPGetOverlappedResult 來等候或輪詢事件物件。

如果 lpCompletionRoutine 不是 Null, 則會忽略 hEvent 成員,而且可由 Windows Sockets SPI 用戶端用來將內容資訊傳遞至完成例程。 將 Null lpCompletionRoutine 和更新版本的用戶端針對相同的重疊 I/O 要求呼叫 WSAGetOverlappedResult,可能不會將該 WSAGetOverlappedResult 叫用的 fWait 參數設定為 TRUE。 在此情況下, 未定義 hEvent 成員的使用方式,而嘗試等候 hEvent 成員會產生無法預期的結果。

服務提供者負責在重疊的作業完成時,排列用戶端指定完成例程的調用。 由於完成例程必須在起始重疊作業的相同線程內容中執行,因此無法直接從服務提供者叫用。 Ws2_32.dll 提供異步過程調用 (APC) 機制,以協助叫用完成例程。

服務提供者會呼叫用來起始重疊作業的 WPUQueueApc,以在適當的線程和進程內容中排列函式。 此函式可以從任何進程和線程內容呼叫,即使是與用來起始重疊作業的線程和進程不同的內容也一樣。

WPUQueueApc 會接受 WSATHREADID 結構的指標, (透過 lpThreadId 輸入參數提供給提供者) 、要叫用的 APC 函式指標,以及後續傳遞至 APC 函式的內容值。 因為只有單一內容值可用,所以 APC 函式本身不能是用戶端指定的完成例程。 服務提供者必須改為提供本身 APC 函式的指標,以使用所提供的內容值來存取重迭作業所需的結果資訊,然後叫用用戶端指定的完成例程。

用戶端提供的完成例程原型如下所示。

void CALLBACK 
CompletionRoutine(  
  IN DWORD           dwError, 
  IN DWORD           cbTransferred, 
  IN LPWSAOVERLAPPED lpOverlapped, 
  IN DWORD           dwFlags 
);

CompletionRoutine 參數是用戶端提供的函式名稱的佔位元。 dwError 會指定重迭作業的完成狀態,如 lpOverlapped 所指出。 cbTransferred 參數會指定收到的位元組數目。 dwFlags 包含當接收作業立即完成時,會出現在 lpFlags 中的資訊。 此函式不會傳回值。

完成例程可以依任何順序呼叫,但不一定是重迭作業完成的順序相同。 不過,保證已張貼的緩衝區會以提供它們的順序填入。

注意

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

規格需求

需求
最低支援的用戶端 Windows 10 組建 20348
最低支援的伺服器 Windows 10 組建 20348
標頭 ws2spi.h

另請參閱

WPUCloseEvent

WPUCreateEvent

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket