Win32 API 日本語リファレンス
ホーム › Networking.WinSock › LPFN_WSASENDMSG

LPFN_WSASENDMSG

コールバック

シグネチャ

INT LPFN_WSASENDMSG(
    SOCKET s,
    WSAMSG* lpMsg,
    DWORD dwFlags,
    DWORD* lpNumberOfBytesSent,
    OVERLAPPED* lpOverlapped,
    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

パラメーター

フィールド型説明
sSOCKET
lpMsgWSAMSG*Posix.1g の msghdr 構造体を格納する WSAMSG 構造体です。
dwFlagsDWORDWSASendMsg 関数呼び出しの動作を変更するために使用するフラグです。詳細については、「解説」セクションの dwFlags の使用方法に関する説明を参照してください。
lpNumberOfBytesSentDWORD*

I/O 操作が即座に完了した場合に、この呼び出しで送信されたバイト数へのポインターです。

誤った結果になる可能性を避けるため、lpOverlapped パラメーターが NULL でない場合は、このパラメーターに NULL を使用してください。このパラメーターを NULL にできるのは、lpOverlapped パラメーターが NULL でない場合のみです。

lpOverlappedOVERLAPPED*WSAOVERLAPPED 構造体へのポインターです。非オーバーラップ ソケットでは無視されます。
lpCompletionRoutineLPWSAOVERLAPPED_COMPLETION_ROUTINE送信操作が完了したときに呼び出される完了ルーチンへのポインターです。非オーバーラップ ソケットでは無視されます。

公式ドキュメント

WSASendMsg 関数は、接続済みおよび未接続のソケットから、データと省略可能な制御情報を送信します。

メモ この関数は、Windows Sockets 仕様に対する Microsoft 固有の拡張です。

戻り値

成功して即座に完了した場合は 0 を返します。0 が返された場合、指定した完了ルーチンは、呼び出し元スレッドがアラート可能状態になったときに呼び出されます。

戻り値が SOCKET_ERROR で、その後の WSAGetLastError の呼び出しが WSA_IO_PENDING を返す場合は、オーバーラップ操作が正常に開始されたことを示します。完了は、イベントや完了ポートなどの別の手段で通知されます。

失敗した場合は SOCKET_ERROR を返し、その後の WSAGetLastError の呼び出しは WSA_IO_PENDING 以外の値を返します。次の表にエラー コードを示します。

エラー コード 意味
WSAEACCES
要求されたアドレスはブロードキャスト アドレスですが、適切なフラグが設定されていませんでした。
WSAECONNRESET
UDP データグラム ソケットの場合、このエラーは、直前の送信操作によって ICMP の「Port Unreachable」メッセージが発生したことを示します。
WSAEFAULT
lpMsg、lpNumberOfBytesSent、lpOverlapped、lpCompletionRoutine のいずれかのパラメーターが、ユーザー アドレス空間の有効な部分に完全には含まれていません。このエラーは、lpMsg パラメーターが指す WSAMSG 構造体の name メンバーが NULL ポインターで、かつ WSAMSG 構造体の namelen メンバーが 0 に設定されていない場合にも返されます。また、lpMsg パラメーターが指す WSAMSG 構造体の Control.buf メンバーが NULL ポインターで、かつ WSAMSG 構造体の Control.len メンバーが 0 に設定されていない場合にも返されます。
WSAEINPROGRESS
ブロッキング型の Windows Sockets 1.1 呼び出しが進行中であるか、サービス プロバイダーがまだコールバック関数を処理しています。
WSAEINTR
ブロッキング型の Windows Socket 1.1 呼び出しが WSACancelBlockingCall によってキャンセルされました。
WSAEINVAL
ソケットが bind でバインドされていないか、ソケットがオーバーラップ フラグを指定して作成されていません。
WSAEMSGSIZE
ソケットがメッセージ指向であり、メッセージが基になるトランスポートでサポートされる最大サイズを超えています。
WSAENETDOWN
ネットワーク サブシステムに障害が発生しました。
WSAENETRESET
データグラム ソケットの場合、このエラーは有効期間 (TTL) が経過したことを示します。
WSAENETUNREACH
ネットワークに到達できません。
WSAENOBUFS
Windows Sockets プロバイダーがバッファーのデッドロックを報告しています。
WSAENOTCONN
ソケットが接続されていません。
WSAENOTSOCK
記述子がソケットではありません。
WSAEOPNOTSUPP
そのソケット操作はサポートされていません。このエラーは、lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーに、WSASendMsg では無効な制御フラグが含まれている場合に返されます。
WSAESHUTDOWN
ソケットはシャットダウンされています。how に SD_SEND または SD_BOTH を指定して shutdown を呼び出した後は、そのソケットで WSASendMsg 関数を呼び出すことはできません。
WSAETIMEDOUT
ソケットがタイムアウトしました。このエラーは、SO_SNDTIMEO ソケット オプションで待機タイムアウトが指定されており、そのタイムアウトを超過した場合に返されます。
WSAEWOULDBLOCK
オーバーラップ ソケットの場合: 未処理のオーバーラップ I/O 要求が多すぎます。非オーバーラップ ソケットの場合: ソケットが非ブロッキングとしてマークされており、送信操作を即座に完了できません。
WSANOTINITIALISED
この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。
WSA_IO_PENDING
オーバーラップ操作が正常に開始され、完了は後で通知されます。
WSA_OPERATION_ABORTED
ソケットが閉じられたか、 WSAIoctl で SIO_FLUSH コマンドが実行されたため、オーバーラップ操作がキャンセルされました。

解説(Remarks)

WSASendMsg 関数は、WSASend 関数および WSASendTo 関数の代わりに使用できます。WSASendMsg 関数は、データグラム ソケットと raw ソケットでのみ使用できます。s パラメーターのソケット記述子は、ソケットの種類を SOCK_DGRAM または SOCK_RAW に設定して開く必要があります。

dwFlags パラメーターには、次の制御フラグの組み合わせのみを指定できます: MSG_DONTROUTE、MSG_PARTIAL、MSG_OOB。lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーは、入力時には無視され、出力にも使用されません。

メモ WSASendMsg 関数の関数ポインターは、実行時に WSAIoctl 関数を SIO_GET_EXTENSION_FUNCTION_POINTER オペコードを指定して呼び出すことで取得する必要があります。WSAIoctl 関数に渡す入力バッファーには、WSASendMsg 拡張関数を識別する値を持つグローバル一意識別子 (GUID) である WSAID_WSASENDMSG を格納する必要があります。成功すると、WSAIoctl 関数が返す出力に WSASendMsg 関数へのポインターが格納されます。WSAID_WSASENDMSG GUID は Mswsock.h ヘッダー ファイルで定義されています。

オーバーラップ ソケットは、WSA_FLAG_OVERLAPPED フラグを設定した WSASocket 関数の呼び出しで作成されます。オーバーラップ ソケットでは、lpOverlapped と lpCompletionRoutine の両方が NULL でない限り、送信にはオーバーラップ I/O が使用されます。lpOverlapped と lpCompletionRoutine がどちらも NULL の場合、そのソケットは非オーバーラップ ソケットとして扱われます。オーバーラップ ソケットでは完了通知が行われ、バッファーがトランスポートによって消費されると、完了ルーチンが呼び出されるか、イベント オブジェクトがシグナル状態になります。操作が即座に完了しない場合、最終的な完了状態は、完了ルーチンを通じて、または WSAGetOverlappedResult 関数を呼び出して取得します。

非オーバーラップ ソケットでは、lpOverlapped パラメーターと lpCompletionRoutine パラメーターは無視され、WSASendMsg は send 関数と同じブロッキング セマンティクスに従います。つまり、データはバッファーからトランスポートのバッファーへコピーされます。ソケットが非ブロッキングかつストリーム指向で、トランスポートのバッファーに十分な空きがない場合、WSASendMsg はアプリケーションのバッファーの一部だけを消費した状態で戻ります。これに対し、ブロッキング ソケットで同じ状況になった場合、WSASendMsg はアプリケーションのバッファーの内容がすべて消費されるまでブロックします。

この関数がオーバーラップ方式で完了する場合、この呼び出しから戻る前に WSABUF 構造体を取り込むのは、Winsock サービス プロバイダーの責任です。これにより、アプリケーションは、lpMsg パラメーターが指す WSAMSG 構造体の lpBuffers メンバーが指す WSABUF 配列をスタック上に構築できます。

メッセージ指向のソケットでは、基になるプロバイダーの最大メッセージ サイズを超えないように注意する必要があります。この値は、ソケット オプション SO_MAX_MSG_SIZE の値を取得することで得られます。データが長すぎて、基になるプロトコルでアトミックに渡せない場合は、エラー WSAEMSGSIZE が返され、データは送信されません。

SOCK_DGRAM 型または SOCK_RAW 型の IPv4 ソケットでは、アプリケーションは、WSASendMsg 関数で送信に使用するローカル IP 送信元アドレスを指定できます。WSASendMsg 関数に WSAMSG 構造体で渡す制御データ オブジェクトの 1 つに、送信に使用するローカル IPv4 送信元アドレスを指定する in_pktinfo 構造体を含めることができます。

SOCK_DGRAM 型または SOCK_RAW 型の IPv6 ソケットでは、アプリケーションは、WSASendMsg 関数で送信に使用するローカル IP 送信元アドレスを指定できます。WSASendMsg 関数に WSAMSG 構造体で渡す制御データ オブジェクトの 1 つに、送信に使用するローカル IPv6 送信元アドレスを指定する in6_pktinfo 構造体を含めることができます。

デュアル スタック ソケットで WSASendMsg 関数によりデータグラムを送信する際に、アプリケーションが特定のローカル IP 送信元アドレスの使用を指定したい場合、その扱い方は宛先 IP アドレスによって異なります。IPv4 の宛先アドレス、または IPv4 射影 IPv6 宛先アドレスに送信する場合は、lpMsg パラメーターが指す WSAMSG 構造体で渡す制御データ オブジェクトの 1 つに、送信に使用するローカル IPv4 送信元アドレスを格納した in_pktinfo 構造体を含める必要があります。IPv4 射影 IPv6 アドレスではない IPv6 宛先アドレスに送信する場合は、lpMsg パラメーターが指す WSAMSG 構造体で渡す制御データ オブジェクトの 1 つに、送信に使用するローカル IPv6 送信元アドレスを格納した in6_pktinfo 構造体を含める必要があります。

メモ SO_SNDTIMEO ソケット オプションは、ブロッキング ソケットにのみ適用されます。
メモ WSASendMsg が正常に完了しても、データが正常に配信されたことを示すわけではありません。
メモ lpOverlapped パラメーターに NULL を指定して WSASendMsg のようなブロッキング型の Winsock 呼び出しを発行した場合、呼び出しが完了する前に Winsock がネットワーク イベントを待機する必要が生じることがあります。この場合、Winsock はアラート可能な待機を行うため、同じスレッドにスケジュールされた非同期プロシージャ呼び出し (APC) によって中断されることがあります。同じスレッドで実行中のブロッキング型 Winsock 呼び出しを中断した APC の内部で、さらに別のブロッキング型 Winsock 呼び出しを発行すると、動作は未定義になります。Winsock クライアントは決してこれを行ってはなりません。

dwFlags

dwFlags 入力パラメーターを使用すると、対象のソケットに指定されたオプションの範囲を超えて、関数呼び出しの動作に影響を与えることができます。つまり、この関数のセマンティクスは、ソケット オプションと dwFlags パラメーターによって決まります。後者は、次の値のいずれかをビットごとの OR 演算子で組み合わせて構成します。
値 意味
MSG_DONTROUTE データをルーティングの対象にしないことを指定します。Windows Sockets サービス プロバイダーは、このフラグを無視することを選択できます。
MSG_PARTIAL lpMsg->lpBuffers にメッセージの一部のみが含まれていることを指定します。部分的なメッセージ送信をサポートしないトランスポートでは、エラー コード WSAEOPNOTSUPP が返されることに注意してください。

dwFlags パラメーターに指定できる値は、Winsock2.h ヘッダー ファイルで定義されています。

出力時には、lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーは使用されません。

オーバーラップ ソケット I/O

オーバーラップ操作が即座に完了した場合、 WSASendMsg は 0 を返し、lpNumberOfBytesSent パラメーターが送信されたバイト数で更新されます。オーバーラップ操作が正常に開始され、後で完了する場合、 WSASendMsg は SOCKET_ERROR を返し、エラー コード WSA_IO_PENDING を示します。この場合、lpNumberOfBytesSent は更新されません。オーバーラップ操作が完了すると、転送されたデータ量は、完了ルーチンの cbTransferred パラメーター (指定されている場合)、または WSAGetOverlappedResult の lpcbTransfer パラメーターで通知されます。
メモ あるスレッドが開始したすべての I/O は、そのスレッドが終了するときにキャンセルされます。オーバーラップ ソケットでは、操作が完了する前にスレッドが閉じられると、保留中の非同期操作が失敗することがあります。詳細については、ExitThread を参照してください。

オーバーラップ I/O を使用する WSASendMsg 関数は、直前の 、WSARecv、 WSARecvFrom、LPFN_WSARECVMSG (WSARecvMsg)、WSASend、WSASendMsg、 WSASendTo の各関数の完了ルーチン内から呼び出すことができます。これにより、時間に敏感なデータ送信を、すべてプリエンプティブなコンテキスト内で行えます。

lpOverlapped パラメーターは、オーバーラップ操作が続いている間、有効である必要があります。複数の I/O 操作が同時に未処理となる場合は、それぞれが別々の WSAOVERLAPPED 構造体を参照する必要があります。

lpCompletionRoutine パラメーターが NULL の場合、lpOverlapped の hEvent パラメーターに有効なイベント オブジェクトのハンドルが格納されていれば、オーバーラップ操作の完了時にそのイベントがシグナル状態になります。アプリケーションは、 WSAWaitForMultipleEvents または WSAGetOverlappedResult を使用して、イベント オブジェクトを待機またはポーリングできます。

lpCompletionRoutine が NULL でない場合、hEvent パラメーターは無視され、アプリケーションが完了ルーチンにコンテキスト情報を渡すために使用できます。NULL 以外の lpCompletionRoutine を渡した呼び出し元が、後で同じオーバーラップ I/O 要求に対して 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 パラメーターは 0 になります。CompletionRoutine 関数は値を返しません。

この関数から戻ると、そのソケットに対する別の保留中の完了ルーチンを呼び出せるようになります。待機中のすべての完了ルーチンは、アラート可能なスレッドの待機が WSA_IO_COMPLETION の戻りコードで満たされる前に呼び出されます。完了ルーチンが呼び出される順序は任意であり、必ずしもオーバーラップ操作が完了した順序とは限りません。ただし、渡されたバッファーは、指定された順序どおりに送信されることが保証されます。

Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストア アプリでサポートされます。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)