WSASendMsg 函式 (winsock2.h)

WSASendMsg 函式會從連線和未連線的套接字傳送數據和選擇性控制資訊。

注意 此函式是 Windows Sockets 規格的 Microsoft 特定延伸模組。

 

語法

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以外的值。 下表列出錯誤碼。

錯誤碼 意義
WSAEACCES
要求的位址是廣播位址,但未設定適當的旗標。
WSAECONNRESET
針對 UDP 數據報套接字,此錯誤會指出先前的傳送作業導致 ICMP「無法連線埠」訊息。
WSAEFAULT
lpMsglpNumberOfBytesSentlpOverlappedlpCompletionRoutine 參數並未完全包含在使用者地址空間的有效部分。 如果 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
如果是資料包通訊端,此錯誤表示已超過存留時間。
WSAENETUNREACH
無法連線到網路。
WSAENOBUFS
Windows Sockets 提供者會報告緩衝區死結。
WSAENOTCONN
未連接此通訊端。
WSAENOTSOCK
描述項不是套接字。
WSAEOPNOTSUPP
不支援套接字作業。 如果 lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員包含 WSASendMsg 無效的任何控件旗標,就會傳回此錯誤。
WSAESHUTDOWN
套接字已關閉;在叫用關閉后,無法在套接字上呼叫 WSASendMsg 函式,以及如何設定為SD_SEND或SD_BOTH。
WSAETIMEDOUT
套接字逾時。如果套接字有使用 SO_SNDTIMEO 套接字選項指定的等候逾時,且超過逾時,就會傳回此錯誤。
WSAEWOULDBLOCK
重疊的套接字:有太多未處理的重疊 I/O 要求。 未重疊的套接字:套接字標示為非封鎖,且無法立即完成傳送作業。
WSANOTINITIALISED
使用此函式之前,必須先進行成功的 WSAStartup 呼叫。
WSA_IO_PENDING
已成功起始重疊的作業,稍後將會指出完成。
WSA_OPERATION_ABORTED
因為套接字關閉,或因為 WSAIoctl 中的 SIO_FLUSH 命令執行,所以已取消重疊的作業。

備註

WSASendMsg 函式可用來取代 WSASendWSASendTo 函式。 WSASendMsg 函式只能與數據報和原始套接字搭配使用。 必須開啟 s 參數中的套接字描述元,並將套接字類型設定為 SOCK_DGRAMSOCK_RAW

dwFlags 參數只能包含下列控件旗標的組合:MSG_DONTROUTEMSG_PARTIALMSG_OOB。 在輸入上忽略 lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員,而不會在輸出上使用。

注意 您必須在運行時間取得 WSASendMsg 函式的函式指標,方法是呼叫 WSAIoctl 函式,並指定 SIO_GET_EXTENSION_FUNCTION_POINTER opcode。 傳遞至 WSAIoctl 函式的輸入緩衝區必須包含 WSAID_WSASENDMSG,這是全域唯一標識碼 (GUID) ,其值可識別 WSASendMsg 擴充函式。 成功時, WSAIoctl 函式所傳回的輸出包含 WSASendMsg 函式的指標。 WSAID_WSASENDMSG GUID 定義於 Mswsock.h 頭檔中。
 

重疊的套接字是使用已設定WSA_FLAG_OVERLAPPED旗標的 WSASocket 函數調用所建立。 對於重疊的套接字,除非 lpOverlappedlpCompletionRoutine 都是 NULL,否則傳送資訊會使用重疊的 I/O;當 lpOverlappedlpCompletionRoutineNULL 時,套接字會被視為非重疊的套接字。 完成指示會與重疊的套接字一起發生;一旦傳輸取用緩衝區或緩衝區,就會觸發完成例程或設定事件物件。 如果作業未立即完成,則會透過完成例程或呼叫 WSAGetOverlappedResult 函式來擷取最終完成狀態。

對於非重迭套接字, 會忽略 lpOverlappedlpCompletionRoutine 參數, 而 WSASendMsg 採用與 傳送 函式相同的封鎖語意:數據會從緩衝區或緩衝區複製到傳輸的緩衝區。 如果套接字為非封鎖和數據流導向,且傳輸緩衝區的空間不足, WSASendMsg 只會傳回應用程式緩衝區的一部分。 相反地,封鎖套接字上的這個緩衝區情況會導致 WSASendMsg 封鎖,直到取用所有應用程式的緩衝區內容為止。

如果此函式是以重疊的方式完成,在從這個呼叫傳回之前,Winsock 服務提供者必須負責擷取此 WSABUF 結構。 這可讓應用程式建置由 lpMsg 參數所指向之 WSAMSG 結構的 lpBuffers 成員所指向的堆疊型 WSABUF 陣列。

對於訊息導向套接字,請務必不要超過基礎提供者的最大訊息大小,這可以藉由取得套接字選項的值 SO_MAX_MSG_SIZE來取得。 如果數據太長而無法透過基礎通訊協議傳遞,則會傳回錯誤 WSAEMSGSIZE ,而且不會傳輸任何數據。

類型為 SOCK_DGRAMSOCK_RAW 的 IPv4 套接字上,應用程式可以指定用來與 WSASendMsg 函 式一起傳送的本機 IP 來源位址。 在 WSAMSG 結構中傳遞至 WSASendMsg 函式的其中一個控件數據物件,可能包含用來指定要用來傳送之本機 IPv4 來源地址 的in_pktinfo 結構。

類型為 SOCK_DGRAMSOCK_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結構以供傳送。

注意SO_SNDTIMEO套接字選項僅適用於封鎖套接字。
 
注意WSASendMsg 成功完成不會指出已成功傳遞數據。
 
注意 發出封鎖的 Winsock 呼叫時,例如 WSASendMsg 並將 lpOverlapped 參數設定為 NULL 時,Winsock 可能需要等候網路事件,才能完成呼叫。 在此情況下,Winsock 會執行可警示的等候,而異步過程調用 (APC) 排程在相同線程上可能會中斷。 在 APC 內發出另一個封鎖 Winsock 呼叫,中斷相同線程上持續封鎖 Winsock 呼叫會導致未定義的行為,而且永遠不會由 Winsock 客戶端嘗試。
 

dwFlags

dwFlags 輸入參數可用來影響函式調用的行為,而超出為相關聯套接字指定的選項。 也就是說,此函式的語意是由套接字選項和 dwFlags 參數所決定。 後者是使用位 OR 運算元搭配下列任何值來建構。
意義
MSG_DONTROUTE 指定數據不應受限於路由。 Windows Sockets 服務提供者可以選擇忽略此旗標。
MSG_PARTIAL 指定 lpMsg-lpBuffers> 只包含部分訊息。 請注意,不支援部分訊息傳輸的傳輸會傳回錯誤碼 WSAEOPNOTSUPP
 

dwFlags 參數的可能值定義在 Winsock2.h 頭檔中。

在輸出時,不會使用 lpMsg 參數所指向之 WSAMSG 結構的 dwFlags 成員。

重疊的套接字 I/O

如果重疊的作業立即完成, WSASendMsg 會傳回值為零,且 lpNumberOfBytesSent 參數會隨著傳送的位元組數目更新。 如果已成功起始重疊的作業,且稍後會完成, WSASendMsg 會傳回SOCKET_ERROR,並指出錯誤碼 WSA_IO_PENDING。 在此情況下,不會更新 lpNumberOfBytesSent 。 當重疊的作業完成時,如果指定) 或透過 WSAGetOverlappedResult 中的 lcbTransfer 參數,則會透過完成例程中的 cbTransfer 參數指出傳輸的數據量 (。
注意 當該線程結束時,指定的線程所起始的所有 I/O 都會取消。 對於重疊的套接字,如果線程在作業完成之前關閉,擱置的異步操作可能會失敗。 如需詳細資訊,請參閱 ExitThread
 

使用重疊 I/O 的 WSASendMsg 函 式可以從先前 、 WSARecvWSARecvFromLPFN_WSARECVMSG (WSARecvMsg) WSASendWSASendMsgWSASendTo 函式內呼叫。 這可讓時間敏感的數據傳輸完全發生在先佔式內容中。

lpOverlapped 參數在重迭作業期間必須有效。 如果同時處理多個 I/O 作業,每個作業都必須參考個別 的 WSAOVERLAPPED 結構。

如果 lpCompletionRoutine 參數為 NULL,當重疊的作業包含有效的事件物件句柄時,lpOverlappedhEvent 參數會發出訊號。 應用程式可以使用 WSAWaitForMultipleEventsWSAGetOverlappedResult 來等候或輪詢事件物件。

如果 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.1Windows 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

另請參閱

ExitThread

IPV6_PKTINFO

IP_PKTINFO

WSABUF

WSACancelBlockingCall

WSAGetLastError

WSAGetOverlappedResult

WSAIoctl

WSAMSG

WSAOVERLAPPED

WSASend

WSASendTo

WSASocket

WSAStartup

WSAWaitForMultipleEvents

Winsock 函式

Winsock 參考

bind

in6_pktinfo

in_pktinfo

send

shutdown