LPFN_WSASENDMSG
コールバックシグネチャ
INT LPFN_WSASENDMSG(
SOCKET s,
WSAMSG* lpMsg,
DWORD dwFlags,
DWORD* lpNumberOfBytesSent,
OVERLAPPED* lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);パラメーター
| フィールド | 型 | 説明 |
|---|---|---|
| s | SOCKET | |
| lpMsg | WSAMSG* | Posix.1g の msghdr 構造体を格納する WSAMSG 構造体です。 |
| dwFlags | DWORD | WSASendMsg 関数呼び出しの動作を変更するために使用するフラグです。詳細については、「解説」セクションの dwFlags の使用方法に関する説明を参照してください。 |
| lpNumberOfBytesSent | DWORD* | I/O 操作が即座に完了した場合に、この呼び出しで送信されたバイト数へのポインターです。 誤った結果になる可能性を避けるため、lpOverlapped パラメーターが NULL でない場合は、このパラメーターに NULL を使用してください。このパラメーターを NULL にできるのは、lpOverlapped パラメーターが NULL でない場合のみです。 |
| lpOverlapped | OVERLAPPED* | WSAOVERLAPPED 構造体へのポインターです。非オーバーラップ ソケットでは無視されます。 |
| lpCompletionRoutine | LPWSAOVERLAPPED_COMPLETION_ROUTINE | 送信操作が完了したときに呼び出される完了ルーチンへのポインターです。非オーバーラップ ソケットでは無視されます。 |
公式ドキュメント
WSASendMsg 関数は、接続済みおよび未接続のソケットから、データと省略可能な制御情報を送信します。
戻り値
成功して即座に完了した場合は 0 を返します。0 が返された場合、指定した完了ルーチンは、呼び出し元スレッドがアラート可能状態になったときに呼び出されます。
戻り値が SOCKET_ERROR で、その後の WSAGetLastError の呼び出しが WSA_IO_PENDING を返す場合は、オーバーラップ操作が正常に開始されたことを示します。完了は、イベントや完了ポートなどの別の手段で通知されます。
失敗した場合は SOCKET_ERROR を返し、その後の WSAGetLastError の呼び出しは WSA_IO_PENDING 以外の値を返します。次の表にエラー コードを示します。
| エラー コード | 意味 |
|---|---|
| 要求されたアドレスはブロードキャスト アドレスですが、適切なフラグが設定されていませんでした。 | |
| UDP データグラム ソケットの場合、このエラーは、直前の送信操作によって ICMP の「Port Unreachable」メッセージが発生したことを示します。 | |
| lpMsg、lpNumberOfBytesSent、lpOverlapped、lpCompletionRoutine のいずれかのパラメーターが、ユーザー アドレス空間の有効な部分に完全には含まれていません。このエラーは、lpMsg パラメーターが指す WSAMSG 構造体の name メンバーが NULL ポインターで、かつ WSAMSG 構造体の namelen メンバーが 0 に設定されていない場合にも返されます。また、lpMsg パラメーターが指す WSAMSG 構造体の Control.buf メンバーが NULL ポインターで、かつ WSAMSG 構造体の Control.len メンバーが 0 に設定されていない場合にも返されます。 | |
| ブロッキング型の Windows Sockets 1.1 呼び出しが進行中であるか、サービス プロバイダーがまだコールバック関数を処理しています。 | |
| ブロッキング型の Windows Socket 1.1 呼び出しが WSACancelBlockingCall によってキャンセルされました。 | |
| ソケットが bind でバインドされていないか、ソケットがオーバーラップ フラグを指定して作成されていません。 | |
| ソケットがメッセージ指向であり、メッセージが基になるトランスポートでサポートされる最大サイズを超えています。 | |
| ネットワーク サブシステムに障害が発生しました。 | |
| データグラム ソケットの場合、このエラーは有効期間 (TTL) が経過したことを示します。 | |
| ネットワークに到達できません。 | |
| Windows Sockets プロバイダーがバッファーのデッドロックを報告しています。 | |
| ソケットが接続されていません。 | |
| 記述子がソケットではありません。 | |
| そのソケット操作はサポートされていません。このエラーは、lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーに、WSASendMsg では無効な制御フラグが含まれている場合に返されます。 | |
| ソケットはシャットダウンされています。how に SD_SEND または SD_BOTH を指定して shutdown を呼び出した後は、そのソケットで WSASendMsg 関数を呼び出すことはできません。 | |
| ソケットがタイムアウトしました。このエラーは、SO_SNDTIMEO ソケット オプションで待機タイムアウトが指定されており、そのタイムアウトを超過した場合に返されます。 | |
| オーバーラップ ソケットの場合: 未処理のオーバーラップ I/O 要求が多すぎます。非オーバーラップ ソケットの場合: ソケットが非ブロッキングとしてマークされており、送信操作を即座に完了できません。 | |
| この関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。 | |
| オーバーラップ操作が正常に開始され、完了は後で通知されます。 | |
| ソケットが閉じられたか、 WSAIoctl で SIO_FLUSH コマンドが実行されたため、オーバーラップ操作がキャンセルされました。 |
解説(Remarks)
WSASendMsg 関数は、WSASend 関数および WSASendTo 関数の代わりに使用できます。WSASendMsg 関数は、データグラム ソケットと raw ソケットでのみ使用できます。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 は 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 構造体を含める必要があります。
dwFlags
dwFlags 入力パラメーターを使用すると、対象のソケットに指定されたオプションの範囲を超えて、関数呼び出しの動作に影響を与えることができます。つまり、この関数のセマンティクスは、ソケット オプションと dwFlags パラメーターによって決まります。後者は、次の値のいずれかをビットごとの OR 演算子で組み合わせて構成します。| 値 | 意味 |
|---|---|
| MSG_DONTROUTE | データをルーティングの対象にしないことを指定します。Windows Sockets サービス プロバイダーは、このフラグを無視することを選択できます。 |
| MSG_PARTIAL | lpMsg->lpBuffers にメッセージの一部のみが含まれていることを指定します。部分的なメッセージ送信をサポートしないトランスポートでは、エラー コード WSAEOPNOTSUPP が返されることに注意してください。 |
出力時には、lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーは使用されません。
オーバーラップ ソケット I/O
オーバーラップ操作が即座に完了した場合、 WSASendMsg は 0 を返し、lpNumberOfBytesSent パラメーターが送信されたバイト数で更新されます。オーバーラップ操作が正常に開始され、後で完了する場合、 WSASendMsg は SOCKET_ERROR を返し、エラー コード WSA_IO_PENDING を示します。この場合、lpNumberOfBytesSent は更新されません。オーバーラップ操作が完了すると、転送されたデータ量は、完了ルーチンの cbTransferred パラメーター (指定されている場合)、または WSAGetOverlappedResult の lpcbTransfer パラメーターで通知されます。オーバーラップ 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 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)