WSASendMsg 函式 (winsock2.h)
WSASendMsg 函式會從連線和未連線的套接字傳送數據和選擇性控制資訊。
語法
int WSAAPI WSASendMsg(
[in] SOCKET Handle,
[in] LPWSAMSG lpMsg,
[in] DWORD dwFlags,
[out] LPDWORD lpNumberOfBytesSent,
[in] LPWSAOVERLAPPED lpOverlapped,
[in] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
參數
[in] Handle
識別套接字的描述項。
[in] lpMsg
儲存Posix.1g msghdr結構的WSAMSG結構。
[in] dwFlags
用來修改 WSASendMsg 函數調用行為的旗標。 如需詳細資訊,請參閱一節中的使用 dwFlags 。
[out] lpNumberOfBytesSent
如果 I/O 作業立即完成,則此呼叫所傳送之數位的指標,以位元組為單位。
如果 lpOverlapped 參數不是 NULL,請針對此參數使用 NULL,以避免發生錯誤的結果。 只有當 lpOverlapped 參數不是 NULL 時,此參數才能為 NULL。
[in] lpOverlapped
WSAOVERLAPPED 結構的指標。 忽略非重疊套接字。
[in] lpCompletionRoutine
類型:_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
傳送作業完成時呼叫之完成例程的指標。 忽略非重疊套接字。
傳回值
成功且立即完成時,傳回零。 當傳回零時,當呼叫線程處於可警示狀態時,就會呼叫指定的完成例程。
傳回值 SOCKET_ERROR,以及傳回WSA_IO_PENDING的 WSAGetLastError 後續呼叫,表示重疊的作業已成功起始;完成接著會透過其他方式表示,例如透過事件或完成埠。
失敗時,傳回 SOCKET_ERROR ,而後續對 WSAGetLastError 的呼叫會傳回 WSA_IO_PENDING以外的值。 下表列出錯誤碼。
錯誤碼 | 意義 |
---|---|
要求的位址是廣播位址,但未設定適當的旗標。 | |
針對 UDP 數據報套接字,此錯誤會指出先前的傳送作業導致 ICMP「無法連線埠」訊息。 | |
lpMsg、lpNumberOfBytesSent、lpOverlapped 或 lpCompletionRoutine 參數並未完全包含在使用者地址空間的有效部分。 如果 lpMsg 參數所指向的 WSAMSG 結構名稱成員是 NULL 指標,且 WSAMSG 結構的 namelen 成員未設定為零,也會傳回此錯誤。 如果 lpMsg 參數所指向之 WSAMSG 結構的 Control.buf 成員是 NULL 指標,且 WSAMSG 結構的 Control.len 成員未設定為零,也會傳回此錯誤。 | |
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或者服務提供者仍在處理回呼函式。 | |
封鎖的 Windows Socket 1.1 呼叫已透過 WSACancelBlockingCall 取消。 | |
套接字尚未系 結系結,或未使用重迭旗標建立套接字。 | |
套接字是訊息導向,而且訊息大於基礎傳輸所支援的最大數目。 | |
網路子系統失敗。 | |
如果是資料包通訊端,此錯誤表示已超過存留時間。 | |
無法連線到網路。 | |
Windows Sockets 提供者會報告緩衝區死結。 | |
未連接此通訊端。 | |
描述項不是套接字。 | |
不支援套接字作業。 如果 lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員包含 WSASendMsg 無效的任何控件旗標,就會傳回此錯誤。 | |
套接字已關閉;在叫用關閉后,無法在套接字上呼叫 WSASendMsg 函式,以及如何設定為SD_SEND或SD_BOTH。 | |
套接字逾時。如果套接字有使用 SO_SNDTIMEO 套接字選項指定的等候逾時,且超過逾時,就會傳回此錯誤。 | |
重疊的套接字:有太多未處理的重疊 I/O 要求。 未重疊的套接字:套接字標示為非封鎖,且無法立即完成傳送作業。 | |
使用此函式之前,必須先進行成功的 WSAStartup 呼叫。 | |
已成功起始重疊的作業,稍後將會指出完成。 | |
因為套接字關閉,或因為 WSAIoctl 中的 SIO_FLUSH 命令執行,所以已取消重疊的作業。 |
備註
WSASendMsg 函式可用來取代 WSASend 和 WSASendTo 函式。 WSASendMsg 函式只能與數據報和原始套接字搭配使用。 必須開啟 s 參數中的套接字描述元,並將套接字類型設定為 SOCK_DGRAM 或 SOCK_RAW。
dwFlags 參數只能包含下列控件旗標的組合:MSG_DONTROUTE、MSG_PARTIAL和MSG_OOB。 在輸入上忽略 lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員,而不會在輸出上使用。
重疊的套接字是使用已設定WSA_FLAG_OVERLAPPED旗標的 WSASocket 函數調用所建立。 對於重疊的套接字,除非 lpOverlapped 和 lpCompletionRoutine 都是 NULL,否則傳送資訊會使用重疊的 I/O;當 lpOverlapped 和 lpCompletionRoutine 為 NULL 時,套接字會被視為非重疊的套接字。 完成指示會與重疊的套接字一起發生;一旦傳輸取用緩衝區或緩衝區,就會觸發完成例程或設定事件物件。 如果作業未立即完成,則會透過完成例程或呼叫 WSAGetOverlappedResult 函式來擷取最終完成狀態。
對於非重迭套接字, 會忽略 lpOverlapped 和 lpCompletionRoutine 參數, 而 WSASendMsg 採用與 傳送 函式相同的封鎖語意:數據會從緩衝區或緩衝區複製到傳輸的緩衝區。 如果套接字為非封鎖和數據流導向,且傳輸緩衝區的空間不足, WSASendMsg 只會傳回應用程式緩衝區的一部分。 相反地,封鎖套接字上的這個緩衝區情況會導致 WSASendMsg 封鎖,直到取用所有應用程式的緩衝區內容為止。
如果此函式是以重疊的方式完成,在從這個呼叫傳回之前,Winsock 服務提供者必須負責擷取此 WSABUF 結構。 這可讓應用程式建置由 lpMsg 參數所指向之 WSAMSG 結構的 lpBuffers 成員所指向的堆疊型 WSABUF 陣列。
對於訊息導向套接字,請務必不要超過基礎提供者的最大訊息大小,這可以藉由取得套接字選項的值 SO_MAX_MSG_SIZE來取得。 如果數據太長而無法透過基礎通訊協議傳遞,則會傳回錯誤 WSAEMSGSIZE ,而且不會傳輸任何數據。
在 類型為 SOCK_DGRAM 或 SOCK_RAW 的 IPv4 套接字上,應用程式可以指定用來與 WSASendMsg 函 式一起傳送的本機 IP 來源位址。 在 WSAMSG 結構中傳遞至 WSASendMsg 函式的其中一個控件數據物件,可能包含用來指定要用來傳送之本機 IPv4 來源地址 的in_pktinfo 結構。
在 類型為 SOCK_DGRAM 或 SOCK_RAW 的 IPv6 套接字上,應用程式可以指定用來與 WSASendMsg 函 式一起傳送的本機 IP 來源位址。 在 WSAMSG 結構中傳遞至 WSASendMsg 函式的其中一個控件數據物件,可能包含用來指定要用來傳送之本機 IPv6 來源地址 的in6_pktinfo 結構。
若是使用 WSASendMsg 函式傳送數據報,而應用程式想要指定要使用的特定本機 IP 來源位址時,要處理的雙堆疊套接字,取決於目的地 IP 位址。 傳送至 IPv4 目的地位址或 IPv4 對應 IPv6 目的地位址時,傳入 lpMsg 參數所指向之 WSAMSG 結構的其中一個控制數據對象應該包含包含用於傳送之本機 IPv4 來源位址的in_pktinfo結構。 傳送至不是 IPv4 對應 IPv6 位址的 IPv6 目的地位址時,在 lpMsg 參數所指向之 WSAMSG 結構中所傳遞的其中一個控件數據對象,應該包含包含包含本機 IPv6 來源位址的in6_pktinfo結構以供傳送。
dwFlags
dwFlags 輸入參數可用來影響函式調用的行為,而超出為相關聯套接字指定的選項。 也就是說,此函式的語意是由套接字選項和 dwFlags 參數所決定。 後者是使用位 OR 運算元搭配下列任何值來建構。值 | 意義 |
---|---|
MSG_DONTROUTE | 指定數據不應受限於路由。 Windows Sockets 服務提供者可以選擇忽略此旗標。 |
MSG_PARTIAL | 指定 lpMsg-lpBuffers> 只包含部分訊息。 請注意,不支援部分訊息傳輸的傳輸會傳回錯誤碼 WSAEOPNOTSUPP 。 |
在輸出時,不會使用 lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員。
重疊的套接字 I/O
如果重疊的作業立即完成, WSASendMsg 會傳回值為零,且 lpNumberOfBytesSent 參數會隨著傳送的位元組數目更新。 如果已成功起始重疊的作業,且稍後會完成, WSASendMsg 會傳回SOCKET_ERROR,並指出錯誤碼 WSA_IO_PENDING。 在此情況下,不會更新 lpNumberOfBytesSent 。 當重疊的作業完成時,如果指定) 或透過 WSAGetOverlappedResult 中的 lcbTransfer 參數,則會透過完成例程中的 cbTransfer 參數指出傳輸的數據量 (。使用重疊 I/O 的 WSASendMsg 函 式可以從先前 、 WSARecv、 WSARecvFrom、 LPFN_WSARECVMSG (WSARecvMsg) 、 WSASend、 WSASendMsg 或 WSASendTo 函式內呼叫。 這可讓時間敏感的數據傳輸完全發生在先佔式內容中。
lpOverlapped 參數在重迭作業期間必須有效。 如果同時處理多個 I/O 作業,每個作業都必須參考個別 的 WSAOVERLAPPED 結構。
如果 lpCompletionRoutine 參數為 NULL,當重疊的作業包含有效的事件物件句柄時,lpOverlapped 的 hEvent 參數會發出訊號。 應用程式可以使用 WSAWaitForMultipleEvents 或 WSAGetOverlappedResult 來等候或輪詢事件物件。
如果 lpCompletionRoutine 不是 NULL, 則會忽略 hEvent 參數,而且可由應用程式用來將內容資訊傳遞至完成例程。 將非 NULLlpCompletionRoutine 和更新版本針對相同重疊 I/O 要求的 WSAGetOverlappedResult 呼叫 WSAGetOverlappedResult 的呼叫端,可能不會將該 WSAGetOverlappedResult 叫用的 fWait 參數設定為 TRUE。 在此情況下, 未定義 hEvent 參數的使用方式,而嘗試等候 hEvent 參數會產生無法預期的結果。
完成例程遵循與 Windows 檔案 I/O 完成例程規定相同的規則。 完成例程在線程處於可警示的等候狀態之前不會叫用,例如,將 WSAWaitForMultipleEvents 呼叫, 並將 fAlertable 參數設定為 TRUE。
傳輸提供者可讓應用程式從套接字 I/O 完成例程的內容中叫用傳送和接收作業,並保證針對指定的套接字,I/O 完成例程不會巢狀化。 這可讓時間敏感的數據傳輸完全發生在先佔式內容中。
完成例程的原型如下所示。
void CALLBACK CompletionRoutine(
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
);
CompletionRoutine 函式是應用程式定義或連結庫定義函數名稱的佔位元。 dwError 參數會指定重迭作業的完成狀態,如 lpOverlapped 參數所指出。 cbTransferred 參數表示傳送的位元組數目。 目前沒有定義旗標值, dwFlags 參數將會是零。 CompletionRoutine 函式不會傳回值。
從此函式傳回允許叫用套接字的另一個擱置完成例程。 所有等候完成例程都會在可警示線程等候符合WSA_IO_COMPLETION的傳回碼之前呼叫。 完成例程可以依任何順序呼叫,不一定以相同順序呼叫重疊作業完成。 不過,所張貼的緩衝區保證會以指定的相同順序傳送。
Windows 8.1和 Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 和更新版本上的 Windows 市集應用程式支援此函式。
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式] |
最低支援的伺服器 | Windows Server 2008 [傳統型應用程式 |UWP 應用程式] |
目標平台 | Windows |
標頭 | winsock2.h (包含 Mswsock.h) |
程式庫 | Ws2_32.lib |
Dll | Ws2_32.dll |
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應