LPFN_WSARECVMSG コールバック関数 (mswsock.h)
LPFN_WSARECVMSG は関数ポインター型です。 一致する WSARecvMsg コールバック関数をアプリに実装します。 システムはコールバック関数を使用して、接続されたソケット経由でメモリ内データ (ファイル データ) に送信します。
WSARecvMsg コールバック関数は、接続されたソケットと接続されていないソケットから、メッセージを含む補助データ/制御情報を受け取ります。
注意
この関数は、Windows ソケット仕様に対する Microsoft 固有の拡張機能です。
構文
LPFN_WSARECVMSG LpfnWsarecvmsg;
INT LpfnWsarecvmsg(
SOCKET s,
LPWSAMSG lpMsg,
LPDWORD lpdwNumberOfBytesRecvd,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
)
{...}
パラメーター
s
型: _In_ SOCKET
ソケットを識別する記述子。
lpMsg
型: _Inout_ LPWSAMSG
msghdr 構造体の Posix.1g 仕様に基づく WSAMSG 構造体へのポインター。
lpdwNumberOfBytesRecvd
WSARecvMsg 操作が直ちに完了した場合に、この呼び出しで受信したバイト数を含む DWORD へのポインター。
誤った可能性のある結果を回避するには、lpOverlapped パラメーターが NULL でない場合は、このパラメーターに NULL を渡します。 このパラメーターは、lpOverlapped パラメーターが NULL でない場合にのみ NULL にすることができます。
lpOverlapped
種類: _INOUT_OPT_ LPWSAOVERLAPPED
WSAOVERLAPPED 構造体へのポインター。 重複しない構造体の場合は無視されます。
lpCompletionRoutine
種類: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
受信操作の完了時に呼び出される完了ルーチンへのポインター。 重複しない構造体の場合は無視されます。
戻り値
エラーが発生せず、受信操作がすぐに完了した場合、 WSARecvMsg は 0 を返します。 この場合、呼び出し元のスレッドが警告可能な状態になると、完了ルーチンは既に呼び出されるようにスケジュールされています。 それ以外の場合は、SOCKET_ERRORの値が返され、 WSAGetLastError を呼び出すことによって特定のエラー コードを取得できます。 エラー コード WSA_IO_PENDING は、重複した操作が正常に開始され、完了が後で示されることを示します。
その他のエラー コードは、操作が正常に開始されなかったことを示し、重複した操作が要求された場合は完了の兆候は発生しません。
エラー コード | 意味 |
---|---|
WSAECONNRESET | UDP データグラム ソケットの場合、このエラーは、以前の送信操作で ICMP "ポートに到達できません" というメッセージが発生したことを示します。 |
WSAEFAULT | lpBuffers、lpFlags、lpFrom、lpNumberOfBytesRecvd、lpFromlen、lpOverlapped、または lpCompletionRoutine パラメーターは、ユーザー アドレス空間の有効な部分に完全に含まれていません。lpFrom バッファーが小さすぎてピア アドレスに対応できませんでした。 このエラーは、lpMsg パラメーターが指す WSAMSG 構造体の名前メンバーが NULL ポインターであり、WSAMSG 構造体の namelen メンバーがゼロに設定されていない場合にも返されます。 このエラーは、lpMsg パラメーターが指す WSAMSG 構造体の Control.buf メンバーが NULL ポインターであり、WSAMSG 構造体の Control.len メンバーがゼロに設定されていない場合にも返されます。 |
WSAEINPROGRESS | ブロックしている Windows ソケット 1.1 呼び出しが進行中であるか、サービス プロバイダーがコールバック関数を処理しています。 |
WSAEINTR | ブロックしている Windows ソケット 1.1 呼び出しが WSACancelBlockingCall によって取り消されました。 |
WSAEINVAL | |
WSAEMSGSIZE | メッセージが大きすぎて指定したバッファーに収まりきらず、(信頼性の低いプロトコルの場合のみ) バッファーに収まらないメッセージの末尾部分が破棄されました。 |
WSAENETDOWN | ネットワーク サブシステムが失敗しました。 |
WSAENETRESET | データグラム ソケットに関して、このエラーは有効期限が切れたことを示します。 |
WSAENOTCONN | ソケットが接続されていません (接続指向ソケットのみ)。 |
WSAETIMEDOUT | ソケットがタイムアウトしました。このエラーは、 ソケットに SO_RCVTIMEO ソケット オプションを使用して指定された待機タイムアウトがあり、タイムアウトを超えた場合に返されます。 |
WSAEOPNOTSUPP | ソケット操作はサポートされていません。 lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーに、非データグラム ソケットのMSG_PEEK制御フラグが含まれている場合、このエラーが返されます。 |
WSAEWOULDBLOCK | Windows NT: 重複するソケット: 未解決の重複した I/O 要求が多すぎます。 重複していないソケット: ソケットは非ブロッキングとしてマークされ、受信操作をすぐに完了することはできません。 |
WSANOTINITIALIZED | この関数を使用する前に 、WSAStartup 呼び出しが正常に行われる必要があります。 |
WSA_IO_PENDING | 重複した操作が正常に開始され、後で完了が示されます。 |
WSA_OPERATION_ABORTED | ソケットが閉じられていたため、重複する操作が取り消されました。 |
注釈
WSARecvMsg 関数は、WSARecv 関数と WSARecvFrom 関数の代わりに使用して、接続されたソケットと接続されていないソケットからデータとオプションの制御情報を受け取ることができます。 WSARecvMsg 関数は、データグラムと生ソケットでのみ使用できます。 s パラメーターのソケット記述子は、ソケット型を SOCK_DGRAM または SOCK_RAW に設定して開く必要があります。
メモWSARecvMsg 関数の関数ポインターは、実行時に、SIO_GET_EXTENSION_FUNCTION_POINTERオペコードを指定して WSAIoctl 関数を呼び出すことによって取得する必要があります。 WSAIoctl 関数に渡される入力バッファーには、WSARecvMsg 拡張関数を識別する値を持つグローバル一意識別子 (GUID) WSAID_WSARECVMSGが含まれている必要があります。 成功すると、 WSAIoctl 関数によって返される出力には、 WSARecvMsg 関数へのポインターが含まれます。 WSAID_WSARECVMSG GUID は、Mswsock.h ヘッダー ファイルで定義されています。
lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーには、入力時にMSG_PEEK制御フラグのみが含まれる場合があります。
重複するソケットは、WSA_FLAG_OVERLAPPED フラグが設定された WSASocket 関数呼び出しで作成されます。 重複するソケットの場合、 lpOverlapped パラメーターと lpCompletionRoutine パラメーターの両方が NULL でない限り、情報を受信すると重複した I/O が使用されます。 lpOverlapped パラメーターと lpCompletionRoutine パラメーターの両方が NULL の場合、ソケットは重複しないソケットとして扱われます。
完了の兆候は、重複するソケットで発生します。 バッファーまたはバッファーがトランスポートによって使用されると、完了ルーチンがトリガーされるか、イベント オブジェクトが設定されます。 操作がすぐに完了しない場合は、完了ルーチンまたは WSAGetOverlappedResult 関数を呼び出すことによって、最終的な完了状態が取得されます。
重複するソケットの場合、 WSARecvMsg は、受信データが使用可能になったときに入ってくるデータを入れるバッファーを 1 つ以上ポストするために使用され、その後、アプリケーション指定の完了指示 (完了ルーチンの呼び出しまたはイベント・オブジェクトの設定) が発生します。 操作がすぐに完了しない場合は、完了ルーチンまたは WSAGetOverlappedResult 関数を介して最終的な完了状態が取得されます。
重複していないソケットの場合、ブロッキング セマンティクスは標準 の recv 関数と同じであり、 lpOverlapped パラメーターと lpCompletionRoutine パラメーターは無視されます。 トランスポートによって既に受信およびバッファリングされているデータは、指定されたユーザー バッファーにコピーされます。 データが現在受信されておらず、トランスポートによってバッファリングされていないブロッキング ソケットの場合、データが受信されるまで呼び出しはブロックされます。 Windows ソケット 2 では、この関数の標準的なブロック タイムアウト メカニズムは定義されていません。 バイト ストリーム プロトコルとして機能するプロトコルの場合、スタックは、使用可能なバッファー領域と使用可能な受信データの量に従って、可能な限り多くのデータを返そうとします。 ただし、呼び出し元のブロックを解除するには、1 バイトの受信で十分です。 1 バイト以上が返される保証はありません。 メッセージ指向として機能するプロトコルの場合、呼び出し元のブロックを解除するには、完全なメッセージが必要です。
メモSO_RCVTIMEO ソケット オプションは、ブロッキング ソケットにのみ適用されます。
バッファーは、lpMsg パラメーターが指す WSAMSG 構造体の lpBuffers メンバーが指す配列に表示される順序で入力され、バッファーは穴が作成されないようにパックされます。
この関数が重複した方法で完了した場合、この呼び出しから戻る前に、この WSABUF 構造体をキャプチャするのは Winsock サービス プロバイダーの責任です。 これにより、アプリケーションは lpMsg パラメーターが指す WSAMSG 構造体の lpBuffers メンバーが指すスタック ベースの WSABUF 配列を構築できます。
メッセージ指向ソケット ( SOCK_DGRAM または SOCK_RAWのソケットの種類) の場合、受信メッセージはバッファーの合計サイズまでのバッファーに配置され、重複したソケットに対して完了の兆候が発生します。 メッセージがバッファーより大きい場合、バッファーにはメッセージの最初の部分が入力され、余分なデータは失われ、 WSARecvMsg はエラー WSAEMSGSIZE を生成します。
IP_PKTINFOソケット・オプションがSOCK_DGRAMタイプまたはSOCK_RAWの IPv4 ソケットで使用可能になっている場合、WSARecvMsg 関数は lpMsg パラメーターが指す WSAMSG 構造体のパケット情報を返します。 返される WSAMSG 構造体の制御データ・オブジェクトの 1 つに、受信パケット・アドレス情報の保管に使用される in_pktinfo 構造体が含まれます。
IPv4 経由で受信したデータグラムの場合、受信した WSAMSG 構造体の Control メンバーには、WSACMSGHDR 構造体を含む WSABUF 構造体が含まれます。 この WSACMSGHDR 構造体のcmsg_levelメンバーには、IPPROTO_IPが含まれます。この構造体のcmsg_type メンバーにはIP_PKTINFOが含まれます。cmsg_data メンバーには、受信した IPv4 パケット アドレス情報を格納するために使用されるin_pktinfo構造体が含まれます。 in_pktinfo構造体の IPv4 アドレスは、パケットの受信元の IPv4 アドレスです。
SOCK_DGRAM またはSOCK_RAW タイプの IPv6 ソケットで IPV6_PKTINFO ソケット オプションが有効になっている場合、WSARecvMsg 関数は lpMsg パラメーターが指す WSAMSG 構造体のパケット情報を返します。 返される WSAMSG 構造体の制御データ・オブジェクトの 1 つに、受信パケット・アドレス情報の保管に使用される in6_pktinfo 構造体が含まれます。
IPv6 経由で受信したデータグラムの場合、受信した WSAMSG 構造体の Control メンバーには、WSACMSGHDR 構造体を含む WSABUF 構造体が含まれます。 この WSACMSGHDR 構造体のcmsg_levelメンバーにはIPPROTO_IPV6が含まれます。この構造体のcmsg_typeメンバーにはIPV6_PKTINFOが含まれます。cmsg_data メンバーには、受信した IPv6 パケット アドレス情報を格納するために使用されるin6_pktinfo構造体が含まれます。 in6_pktinfo構造体の IPv6 アドレスは、パケットの受信元の IPv6 アドレスです。
デュアル スタック データグラム ソケットの場合、アプリケーションで WSARecvMsg 関数が IPv4 経由で受信したデータグラムの WSAMSG 構造体でパケット情報を返す必要がある場合は、 ソケットで IP_PKTINFO ソケット オプションを true に設定する必要があります。 ソケットで IPV6_PKTINFO オプションのみが true に設定されている場合、IPv6 経由で受信したデータグラムに対してパケット情報が提供されますが、IPv4 経由で受信したデータグラムには提供されない場合があります。
Ws2ipdef.h ヘッダー ファイルは Ws2tcpip.h に自動的に含まれるので、直接使用しないでください。
メモ 特定のスレッドによって開始されたすべての I/O は、そのスレッドが終了すると取り消されます。 重複するソケットの場合、操作が完了する前にスレッドが閉じられた場合、保留中の非同期操作が失敗する可能性があります。 詳細については、「 ExitThread」を参照してください。
Windows Phone 8: この関数は、Windows Phone 8 以降のWindows Phone ストア アプリでサポートされています。
Windows 8.1とWindows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストア アプリでサポートされています。
dwFlags
入力時には、lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーを使用して、関連するソケットに指定されたソケット・オプションを超えて関数呼び出しの動作に影響を与えることができます。 つまり、この関数のセマンティクスは、ソケット オプションと WSAMSG 構造体の dwFlags メンバーによって決まります。 lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーに指定できる入力値は、MSG_PEEKのみです。
値 | 意味 |
---|---|
MSG_PEEK | 受信データにプレビューします。 データはバッファーにコピーされますが、入力キューからは削除されません。 このフラグは、重複していないソケットに対してのみ有効です。 |
入力時に dwFlags メンバーに指定できる値は、 Winsock2.h ヘッダー ファイルで定義されています。
出力時に、lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーは、次のいずれかの値の組み合わせを返す場合があります。
値 | 意味 |
---|---|
MSG_BCAST | データグラムは、リンク層ブロードキャストとして、またはブロードキャスト アドレスである宛先 IP アドレスで受信されました。 |
MSG_CTRUNC | コントロール (補助) データが切り捨てられました。 割り当てられたプロセスの部屋よりも多くの制御データが存在しました。 |
MSG_MCAST | データグラムは、マルチキャスト アドレスである宛先 IP アドレスで受信されました。 |
MSG_TRUNC | データグラムが切り捨てられました。 割り当てられたプロセスのスペースよりも多くのデータが存在しました。 |
Windows Vista 以降用にリリースされた Microsoft Windows ソフトウェア開発キット (Windows SDK) (SDK) では、ヘッダー ファイルのorganizationが変更され、出力時に dwFlags メンバーに指定できる値は、Winsock2.h ヘッダー ファイルによって自動的に含まれる Ws2def.h ヘッダー ファイルで定義されます。
Windows Server 2003 以前のプラットフォーム ソフトウェア開発キット (SDK) のバージョンでは、出力時に dwFlags メンバーに指定できる値は Mswsock.h ヘッダー ファイルで定義されています。
メモlpOverlapped パラメーターを NULL に設定して WSARecvMsg などのブロッキング Winsock 呼び出しを発行する場合、Winsock は呼び出しを完了する前にネットワーク イベントを待機する必要がある場合があります。 Winsock は、この状況でアラート可能な待機を実行します。この待機は、同じスレッドでスケジュールされた非同期プロシージャ 呼び出し (APC) によって中断される可能性があります。 同じスレッドで進行中の Winsock 呼び出しを中断した APC 内で別のブロック Winsock 呼び出しを発行すると、未定義の動作が発生し、Winsock クライアントが試行することはできません。
重複するソケット I/O
重複した操作が直ちに完了すると、 WSARecvMsg は 0 の値を返し、 lpNumberOfBytesRecvd パラメーターは受信したバイト数で更新され、 lpFlags パラメーターによって示されるフラグ ビットも更新されます。 重複した操作が正常に開始され、後で完了する場合、WSARecvMsg はSOCKET_ERRORを返し、エラー コードWSA_IO_PENDINGを示します。 この場合、 lpNumberOfBytesRecvd は更新されません。 重複する操作が完了すると、転送されるデータの量は、完了ルーチンの cbTransferred パラメーター (指定されている場合) または WSAGetOverlappedResult の lpcbTransfer パラメーターを使用して示されます。 フラグ値は、WSAGetOverlappedResult の lpdwFlags パラメーターを調べることによって取得されます。
重複した I/O を使用する WSARecvMsg 関数は、前の WSARecv、WSARecvFrom、WSARecvMsg、WSASend、WSASendMsg、または WSASendTo 関数の完了ルーチン内から呼び出すことができます。 特定のソケットの場合、I/O 完了ルーチンは入れ子になりません。 これにより、時間の影響を受けやすいデータ転送は、プリエンプティブ コンテキスト内で完全に行われます。
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 完了ルーチンに規定されているのと同じ規則に従います。 fAlertable パラメーターが TRUE に設定された関数 WSAWaitForMultipleEvents が呼び出されたときに、スレッドがアラート可能な待機状態になるまで、完了ルーチンは呼び出されません。
完了ルーチンのプロトタイプは次のとおりです。
void CALLBACK CompletionRoutine(
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
);
CompletionRoutine は、アプリケーション定義またはライブラリ定義関数名のプレースホルダーです。 dwError パラメーターは、lpOverlapped パラメーターで示されているように、重複する操作の完了状態を指定します。 cbTransferred パラメーターは、受信したバイト数を指定します。 dwFlags パラメーターには、受信操作がすぐに完了した場合に lpMsg パラメーターが指す WSAMSG 構造体の dwFlags メンバーでも返される情報が含まれます。 CompletionRoutine 関数は値を返しません。
この関数から戻って、このソケットに対して別の保留中の完了ルーチンを呼び出すことができます。 WSAWaitForMultipleEvents を使用する場合、警告可能スレッドの待機がWSA_IO_COMPLETIONの戻りコードで満たされる前に、すべての待機完了ルーチンが呼び出されます。 完了ルーチンは任意の順序で呼び出すことができます。重複する操作が完了した順序と同じ順序であるとは限りません。 ただし、ポストされたバッファーは、指定された順序と同じ順序で入力することが保証されます。
I/O 完了ポートを使用している場合は、 WSARecvMsg に対して行われた呼び出しの順序も、バッファーが設定される順序であることに注意してください。 WSARecvMsg 関数は、予期しないバッファー順序になる可能性があるため、異なるスレッドから同じソケットで同時に呼び出さないでください。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows 10 ビルド 20348 |
サポートされている最小のサーバー | Windows 10 ビルド 20348 |
Header | mswsock.h |