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 函數調用行為的旗標。 如需詳細資訊,請參閱一節中的using 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 參數未完全包含在使用者地址空間的有效部分中。 如果 |
|
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。 | |
封鎖的 Windows Socket 1.1 呼叫已透過 WSACancelBlockingCall取消。 | |
套接字尚未系結 系結,或未使用重迭旗標建立套接字。 | |
套接字是訊息導向,而且訊息大於基礎傳輸所支援的最大數目。 | |
網路子系統失敗。 | |
針對數據報套接字,此錯誤表示存留時間已過期。 | |
網路無法連線。 | |
Windows Sockets 提供者會報告緩衝區死結。 | |
套接字未連線。 | |
描述元不是套接字。 | |
不支援套接字作業。 如果 |
|
套接字已關閉;關機 叫用后,無法在套接字上呼叫 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。 dwFlagsWSAMSG 結構的成員,lpMsg 參數在輸入上會被忽略,而且不會用於輸出。
重疊的套接字是使用已設定 WSA_FLAG_OVERLAPPED 旗標的 WSASocket 函式調用所建立。 若為重疊的套接字,除非 lpOverlapped 和 lpCompletionRoutine 都 NULL,否則傳送資訊會使用重疊的 I/O;當 lpOverlapped 和 lpCompletionRoutineNULL時,套接字會被視為非重迭套接字。 完成指示會與重疊的套接字一起發生;傳輸取用緩衝區或緩衝區之後,就會觸發完成例程,或設定事件物件。 如果作業未立即完成,則會透過完成例程或呼叫 WSAGetOverlappedResult 函式來擷取最終完成狀態。
針對非重迭套接字,lpOverlapped 和 lpCompletionRoutine 參數會被忽略,WSASendMsg 採用與 傳送 函式相同的封鎖語意:數據會從緩衝區或緩衝區複製到傳輸的緩衝區。 如果套接字為非封鎖和數據流導向,且傳輸緩衝區的空間不足,WSASendMsg 只會傳回應用程式緩衝區的一部分。 相反地,封鎖套接字上的這個緩衝區狀況會導致 WSASendMsg 封鎖,直到取用所有應用程式的緩衝區內容為止。
如果此函式是以重疊的方式完成,則 Winsock 服務提供者有責任先擷取此 WSABUF 結構,再從這個呼叫傳回。 這可讓應用程式建置堆疊型 WSABUF 陣列,lpBuffers 所指向的 WSAMSG 結構 成員 lpMsg 參數所指向。
對於訊息導向套接字,必須小心不要超過基礎提供者的訊息大小上限,這可以透過取得套接字選項的值來取得 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 目的地位址時,傳入 WSAMSG 結構中傳遞的其中一個控制數據物件,lpMsg 參數所指向的控件數據對象應該包含 in_pktinfo 結構,其中包含要用於傳送的本機 IPv4 來源位址。 傳送至不是 IPv4 對應 IPv6 位址的 IPv6 目的地位址時,傳入 WSAMSG 結構中傳遞的其中一個控制數據物件,lpMsg 參數所指向的其中一個控制數據對象應該包含 in6_pktinfo 結構,其中包含要用於傳送的本機 IPv6 來源位址。
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。 重疊作業完成時,會透過完成例程中的 cbTransferred 參數,或透過 WSAGetOverlappedResult中的 lcbTransfer 參數來表示傳輸的數據量。使用重疊 I/O 的
lpOverlapped 參數在重迭作業期間必須有效。 如果同時未處理多個 I/O 作業,則每個作業都必須參考個別 WSAOVERLAPPED 結構。
如果 lpCompletionRoutine 參數 NULL,則當重疊作業包含有效事件物件句柄時,lpOverlapped 的 hEvent 參數會發出訊號。 應用程式可以使用 WSAWaitForMultipleEvents 或 WSAGetOverlappedResult 等候或輪詢事件物件。
如果 lpCompletionRoutine 未 NULL,則會忽略 hEvent 參數,而且應用程式可以使用將內容資訊傳遞至完成例程。 針對相同重疊的 I/O 要求,傳遞非NULLlpCompletionRoutine 和更新版本的呼叫 WSAGetOverlappedResult,可能無法針對該調用 WSAGetOverlappedRes ult TRUE設定 fWait 參数。 在此情況下,未定義 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 應用程式] |
目標平臺 | 窗戶 |
標頭 | winsock2.h (包括 Mswsock.h) |
連結庫 | Ws2_32.lib |
DLL | Ws2_32.dll |