共用方式為


LPWSPRECVFROM 回呼函式 (ws2spi.h)

LPWSPRecvFrom函式會接收資料包並儲存來源位址。

語法

LPWSPRECVFROM Lpwsprecvfrom;

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

參數

[in] s

識別通訊端的描述項。

[in, out] lpBuffers

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

[in] dwBufferCount

lpBuffers陣列中的WSABUF結構數目。

[out] lpNumberOfBytesRecvd

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

[in, out] lpFlags

旗標的指標。

[out] lpFrom

sockaddr結構中緩衝區的選擇性指標,會在重迭作業完成時保存來源位址。

[in, out] lpFromlen

只有在指定 lpFrom 時,才需要以位元組為單位的 lpFrom 緩衝區大小指標。

[in] lpOverlapped

未重迭通訊端) 忽略 WSAOverlapped 結構的指標 (。

[in] lpCompletionRoutine

類型:_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

當接收作業完成時呼叫的完成常式指標, (忽略非重迭通訊端) 。

\\[in\\] lpThreadId

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

[in, out] lpErrno

錯誤碼的指標。

傳回值

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

錯誤碼 意義
WSAENETDOWN
網路子系統失敗。
WSAEFAULT
lpFromlen參數無效:lpFrom緩衝區太小,無法容納對等位址或lpbuffers完全不包含在使用者位址空間的有效部分內。
WSAEINTR
(封鎖) 呼叫已透過 LPWSPCancelBlockingCall取消。
WSAEINPROGRESS
封鎖 Windows Sockets 呼叫正在進行中,或者服務提供者仍在處理回呼函式。
WSAEINVAL
通訊端尚未系結 (例如 ,使用 LPWSPBind) ,或未使用重迭旗標建立通訊端。
WSAEISCONN
通訊端已連接。 不論通訊端是連線導向還是無連線,此函式都不允許與連線的通訊端搭配使用。
WSAENETRESET
連線已中斷,因為持續活動偵測到作業正在進行時失敗。
WSAENOTSOCK
描述項不是通訊端。
WSAEOPNOTSUPP
已指定MSG_OOB,但通訊端不是資料流程樣式,例如類型SOCK_STREAM、與此通訊端相關聯的通訊網域不支援 OOB 資料,或通訊端是單向的,而且只支援傳送作業。
WSAESHUTDOWN
通訊端已關閉;叫用LPWSPShutdown之後,無法在通訊端上執行LPWSPRecvFrom,以及如何設定為 SD_RECEIVE 或 SD_BOTH。
WSAEWOULDBLOCK
**Windows NT:**
重迭的通訊端:有太多未處理的重迭 I/O 要求。未重迭的通訊端:通訊端標示為非封鎖,且無法立即完成接收作業。
WSAEMSGSIZE
訊息太大而無法放入指定的緩衝區中,而且 (的不可靠通訊協定,只會) 未放入緩衝區之訊息的任何尾端部分遭到捨棄。
WSAECONNRESET
執行硬式或失敗關閉的遠端部分已重設此虛擬電路。 此通訊端無法再使用,應用程式應予以關閉。 在 UDP 資料包通訊端上,此錯誤表示先前的傳送作業導致 ICMP「無法連線」訊息。
WSAEDISCON
通訊端是訊息導向,而虛擬線路會由遠端正常關閉。
WSA_IO_PENDING
已成功起始重迭的作業,稍後將會指出完成。
WSA_OPERATION_ABORTED
由於通訊端關閉,已取消重迭的作業。

備註

LPWSPRecvFrom函式主要用於s指定的無連線通訊端上,通訊端不得連接。 必須知道通訊端的本機位址。 這可以透過 LPWSPBind 明確完成,或透過 LPWSPSendToLPWSPJoinLeaf隱含完成。

對於重迭的通訊端,此函式會用來張貼一或多個要放置傳入資料的緩衝區,因為它會在 (可能連線的) 通訊端上使用,之後用戶端指定的完成指示會 (叫用完成常式或事件物件) 的設定。 如果作業未立即完成,則會透過完成常式或 LPWSPGetOverlappedResult擷取最終完成狀態。 另請注意,在指示完成之前, 不會更新 lpFromlpFromlen 所指向的值。 應用程式在更新這些值之前,不得使用或干擾這些值,因此用戶端不得針對這些參數使用以堆疊為基礎的) 變數自動 (。

如果 lpOverlappedlpCompletionRoutine 都是 Null,此函式中的通訊端將會被視為非重迭的通訊端。

若為非重迭通訊端,則會忽略 lpOverlappedlpCompletionRoutinelpThreadId 參數。 傳輸已接收和緩衝的任何資料都會複製到提供的使用者緩衝區。 對於目前尚未接收和緩衝傳輸之資料的封鎖通訊端案例,呼叫將會封鎖,直到根據 LPWSPRecv指派的封鎖語意接收資料為止。

提供的緩衝區會填入它們出現在 lpBuffers所指向的陣列中的順序,並封裝緩衝區,這樣就不會建立任何漏洞。

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

針對無連線通訊端類型,資料來源的位址會複製到 lpFrom所指向的緩衝區。 在輸入時, lpFromlen 所指向的值會初始化為此緩衝區的大小,並在完成時修改,以指出儲存在該處之位址的實際大小。

如先前所述,重迭通訊端的 lpFromlpFromlen 參數在重迭 I/O 完成之前不會更新。 因此,這些參數所指向的記憶體必須可供服務提供者使用,而且無法在 Windows Sockets SPI 用戶端的堆疊框架上配置。 連接導向通訊端會忽略 lpFromlpFromlen 參數。

例如,針對位元組資料流程樣式通訊端 (輸入 SOCK_STREAM) ,傳入的資料會放在緩衝區中,直到緩衝區填滿、連接已關閉或內部緩衝的資料耗盡為止。 不論傳入的資料是否填滿所有緩衝區,重迭通訊端都會發生完成指示。

針對訊息導向通訊端,單一傳入訊息會放在提供的緩衝區中,最多提供緩衝區的大小總計,而重迭通訊端的完成指示就會發生。 如果訊息大於提供的緩衝區,則緩衝區會填入訊息的第一個部分。 如果服務提供者支援MSG_PARTIAL功能,MSG_PARTIAL旗標會在通訊端的 lpFlags 中設定,後續的接收作業 () 將會擷取其餘訊息。 如果不支援MSG_PARTIAL,但通訊協定可靠, LPWSPRecvFrom 會產生錯誤 WSAEMSGSIZE ,以及具有較大緩衝區的後續接收作業可用來擷取整個訊息。 否則, (即通訊協定不可靠,且不支援MSG_PARTIAL) 、遺失過多的資料, 而 LPWSPRecvFrom 會產生錯誤 WSAEMSGSIZE。

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

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

 

 

對於訊息導向通訊端,如果收到部分訊息,MSG_PARTIAL位會在 lpFlags 參數中設定。 如果收到完整的訊息,MSG_PARTIAL 會在 lpFlags中清除。 在延遲完成的情況下, 不會更新 lpFlags 所指向的值。 當指出完成時,Windows Sockets SPI 用戶端應該呼叫 LPWSPGetOverlappedResult ,並檢查 lpdwFlags 參數所指向的旗標。

如果重迭的作業立即完成, 則 LPWSPRecv 會傳回值為零,且 lpNumberOfBytesRecvd 參數會更新已接收的位元組數目,而且 也會更新 lpFlags 參數所指向的旗標位。 如果重迭的作業已成功起始,且稍後將會完成, LPWSPRecv 會傳回SOCKET_ERROR,並指出錯誤碼 WSA_IO_PENDING。 在此情況下,不會更新 lpNumberOfBytesRecvdlpFlags 。 當重迭的作業完成時,如果指定) ,或透過LPWSPGetOverlappedResult中的lxmlTransfer參數,則透過完成常式中的cbTransfer參數來指出傳輸的資料量 (。 旗標值是藉由檢查LPWSPGetOverlappedResultlpdwFlags參數來取得。

提供者必須允許從先前LPWSPRecv、LPWSPRecvFromLPWSPSend 或 LPWSPSendTo函式的完成常式內呼叫此函式。 不過,對於指定的通訊端,I/O 完成常式不能巢狀化。 這可讓時間敏感的資料傳輸完全發生在先占式內容內。

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

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

如果 lpCompletionRoutine 不是 Null, 則會忽略 hEvent 成員,而且可由 Windows Sockets SPI 用戶端用來將內容資訊傳遞至完成常式。 服務提供者負責在重迭的作業完成時,排列用戶端指定完成常式的調用。 由於完成常式必須在起始重迭作業的相同執行緒內容中執行,因此無法直接從服務提供者叫用。 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 2000 專業版 [僅限傳統型應用程式]
最低支援的伺服器 Windows 2000 Server [僅限傳統型應用程式]
標頭 ws2spi.h

另請參閱

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket