次の方法で共有


LPWSPRECV コールバック関数 (ws2spi.h)

LPWSPRecv 関数は、ソケット上のデータを受け取ります。

構文

LPWSPRECV Lpwsprecv;

int Lpwsprecv(
  [in]         SOCKET s,
  \[in\, out\] LPWSABUF lpBuffers,
  [in]         DWORD dwBufferCount,
  [out]        LPDWORD lpNumberOfBytesRecvd,
  \[in\, out\] LPDWORD lpFlags,
  [in]         LPWSAOVERLAPPED lpOverlapped,
  [in]         LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  [in]         LPWSATHREADID lpThreadId,
  [out]        LPINT lpErrno
)
{...}

パラメーター

[in] s

接続されているソケットを識別する記述子。

\\[in\\, out\\] lpBuffers

WSABUF 構造体の配列へのポインター。 各 WSABUF 構造体には、バッファーへのポインターとバッファーの長さ (バイト単位) が含まれています。

[in] dwBufferCount

lpBuffers 配列内の WSABUF 構造体の数。

[out] lpNumberOfBytesRecvd

この呼び出しで受信したバイト数へのポインター。

\\[in\\, out\\] lpFlags

呼び出しの方法を指定するフラグへのポインター。

[in] lpOverlapped

WSAOverlapped 構造体へのポインター (オーバーラップされていない構造体の場合は無視されます)。

[in] lpCompletionRoutine

種類: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

受信操作が完了したときに呼び出される完了ルーチンへのポインター (オーバーラップされていない構造体の場合は無視されます)。

[in] lpThreadId

WPUQueueApc への後続の呼び出しでプロバイダーによって使用される WSATHREADID 構造体へのポインター。 プロバイダーは、WPUQueueApc 関数が戻るまで、参照先の WSATHREADID 構造体 (同じへのポインターではありません) を格納する必要があります。

[out] lpErrno

エラー コードへのポインター。

戻り値

エラーが発生せず、受信操作がすぐに完了した場合、 LPWSPRecv は 0 を返します。 この場合、完了ルーチン (指定されている場合) は既にキューに登録されていることに注意してください。 それ以外の場合は、SOCKET_ERRORの値が返され、 lpErrno で特定のエラー コードを使用できます。 エラー コード WSA_IO_PENDINGは、重複した操作が正常に開始され、完了が後で示されることを示します。 その他のエラー コードは、重複する操作が開始されておらず、完了の兆候も発生しなかったことを示します。

エラー コード 意味
WSAENETDOWN
ネットワーク サブシステムが失敗しました。
WSAENOTCONN
ソケットが接続されていません。
WSAEINTR
(ブロッキング) 呼び出しは LPWSPCancelBlockingCall を介して取り消されました。
WSAEINPROGRESS
Windows ソケット呼び出しのブロックが進行中であるか、サービス プロバイダーがコールバック関数を処理しています。
WSAENETRESET
操作の実行中にキープ アライブ動作によってエラーが検出されたため、接続が切断されました。
WSAEFAULT
lpBuffers パラメーターは、ユーザー アドレス空間の有効な部分に完全には含まれていません。
WSAENOTSOCK
記述子はソケットではありません。
WSAEOPNOTSUPP
MSG_OOB指定されましたが、ソケットは、型SOCK_STREAM、OOB データがこのソケットに関連付けられている通信ドメインでサポートされていない、またはソケットが一方向であり、送信操作のみをサポートするなど、ストリーム スタイルではありません。
WSAESHUTDOWN
ソケットがシャットダウンされました。LPWSPShutdown が SD_RECEIVE または SD_BOTH に設定された状態で呼び出された後、ソケットで LPWSPRecv を介して受信することはできません。
WSAEWOULDBLOCK
Windows NT: 重複するソケット: 未解決の重複した I/O 要求が多すぎます。 非オーバーラップ ソケット: ソケットは非ブロッキングとしてマークされ、受信操作をすぐに完了することはできません。
WSAEMSGSIZE
メッセージが大きすぎて指定したバッファーに収まりきらず、(信頼性の低いプロトコルの場合のみ) バッファーに収まらないメッセージの末尾部分が破棄されました。
WSAEINVAL
ソケットがバインドされていない ( LPWSPBind など) か、重複するフラグでソケットが作成されていません。
WSAECONNABORTED
タイムアウトまたはその他の障害が原因で仮想回線が終了しました。
WSAECONNRESET
リモート側で仮想回線がリセットされました。
WSAEDISCON
ソケット s はメッセージ指向であり、仮想回線はリモート側で正常に閉じられました。
WSA_IO_PENDING
重複した操作が正常に開始され、後で完了が示されます。
WSA_OPERATION_ABORTED
ソケットが閉じられていたため、重複する操作が取り消されました。

注釈

LPWSPRecv、 パラメーターで 指定された接続ソケットまたはバインドされたコネクションレス ソケットで使用され、受信データの読み取りに使用されます。 ソケットのローカル アドレスは既知である必要があります。 これは、LPWSPBind を介して明示的に行うか、LPWSPAccept、LPWSPConnectLPWSPSendTo、または LPWSPJoinLeaf を介して暗黙的に行うことができます。

接続されたコネクションレス ソケットの場合、この関数は、受信したメッセージの受け入れ元のアドレスを制限します。 関数は、接続で指定されたリモート アドレスからのみメッセージを返します。 他のアドレスからのメッセージは (サイレントに) 破棄されます。

重複するソケットの場合、 LPWSPRecv は、受信データが使用可能になったときに格納される 1 つ以上のバッファーをポストするために使用されます。その後、Windows Sockets SPI クライアント指定の完了指示 (完了ルーチンの呼び出しまたはイベント オブジェクトの設定) が発生します。 操作がすぐに完了しない場合は、完了ルーチンまたは LPWSPGetOverlappedResult を介して最終的な完了状態が取得されます。

lpOverlappedlpCompletionRoutine の両方が null の場合、この関数のソケットは、オーバーラップされていないソケットとして扱われます。

オーバーラップされていないソケットの場合、 lpOverlappedlpCompletionRoutine、および lpThreadId パラメーターは無視されます。 トランスポートによって既に受信およびバッファリングされているデータは、指定されたユーザー バッファーにコピーされます。 トランスポートによって現在受信およびバッファリングされているデータがないブロッキング ソケットの場合、呼び出しはデータが受信されるまでブロックされます。 Windows ソケット 2 では、この関数の標準的なブロック タイムアウト メカニズムは定義されていません。 バイト ストリーム プロトコルとして機能するプロトコルの場合、スタックは、指定されたバッファー領域と使用可能な受信データの量に従って、可能な限り多くのデータを返そうとします。 ただし、呼び出し元のブロックを解除するには、1 バイトの受信で十分です。 1 バイト以上が返される保証はありません。 メッセージ指向として機能するプロトコルの場合、呼び出し元のブロックを解除するには、完全なメッセージが必要です。

プロトコルがバイト ストリームとして機能するかどうかは、 WSAPROTOCOL_INFO構造体の XP1_MESSAGE_ORIENTEDとXP1_PSEUDO_STREAMの設定と、この関数に渡されるMSG_PARTIAL フラグの設定 (それをサポートするプロトコルの場合) によって決まります。 関連する組み合わせを次の表にまとめます (アスタリスク (*) は、このビットの設定がこの場合は関係ないことを示します)。

XP1_MESSAGE_ORIENTED XP1_PSEUDO_STREAM MSG_PARTIAL として機能する
設定しない * * バイト ストリーム
* set * バイト ストリーム
set 設定しない set バイト ストリーム
set 設定しない 設定しない メッセージ指向

指定されたバッファーは 、lpBuffers が指す配列に出現する順序で塗りつぶされ、バッファーは穴が作成されないようにパックされます。

lpBuffers パラメーターが指す WSABUF 構造体の配列は一時的なものです。 この操作が重複して完了した場合、この呼び出しから戻る前に 、WSABUF 構造体へのポインターのこの配列をキャプチャするのはサービス プロバイダーの責任です。 これにより、Windows ソケット SPI クライアントはスタック ベースの WSABUF 配列を構築できます。

バイト ストリーム スタイルのソケット (たとえば、SOCK_STREAM型) の場合、バッファーが入力されるか、接続が閉じられるか、内部的にバッファーに格納されたデータが使い果たされるまで、受信データがバッファーに配置されます。 受信データがすべてのバッファーを満たすかどうかに関係なく、重複するソケットに対して完了の兆候が発生します。 メッセージ指向ソケット (例: SOCK_DGRAM) の場合、指定したバッファーの合計サイズまで受信メッセージが指定されたバッファーに配置され、重複するソケットに対して完了の表示が発生します。 メッセージが指定されたバッファーより大きい場合、バッファーにはメッセージの最初の部分が入力されます。 MSG_PARTIAL機能がサービス プロバイダーによってサポートされている場合、MSG_PARTIAL フラグは lpFlags に設定され、後続の受信操作を使用してメッセージの残りの部分を取得できます。 MSG_PARTIALがサポートされておらず、プロトコルが信頼できる場合、 LPWSPRecv はエラー WSAEMSGSIZE を生成し、後続の受信操作を大きなバッファーで使用してメッセージ全体を取得できます。 それ以外の場合 (つまり、プロトコルは信頼性が低く、MSG_PARTIALをサポートしていません)、余分なデータが失われ、 LPWSPRecv によってエラー WSAEMSGSIZE が生成されます。

接続指向ソケットの場合、 LPWSPRecv は、ソケットがバイト・ストリームであるかメッセージ指向であるかに応じて、2 つの方法のいずれかで仮想回線の正常終了を示すことができます。 バイト ストリームの場合、読み取られた 0 バイトは正常なクローズを示し、それ以上のバイトは読み取られなくなります。 多くの場合、0 バイト のメッセージが許可されるメッセージ指向ソケットの場合、 WSAEDISCON の戻りエラー コードを使用して、正常な終了を示します。 いずれの場合も、 WSAECONNRESET の戻りエラー コードは、中止終了が発生したことを示します。

lpFlags パラメーターを使用すると、関連付けられたソケットに指定されたオプションを超えて、関数呼び出しの動作に影響を与えることができます。 つまり、この関数のセマンティクスは、ソケット オプションと lpFlags パラメーターによって決定されます。 後者は、次のいずれかの値を持つビットごとの OR 演算子を使用して構築されます。

意味
MSG_PEEK 受信データをピークします。 データはバッファーにコピーされますが、入力キューからは削除されません。 このフラグは、オーバーラップされていないソケットに対してのみ有効です。
MSG_OOB 帯域外 (OOB) データを処理します。
MSG_PARTIAL このフラグは、メッセージ指向ソケット専用です。 出力時に、 は、指定されたデータが送信者によって送信されるメッセージの一部であることを示します。 メッセージの残りの部分は、後続の受信操作で提供されます。 MSG_PARTIAL フラグがクリアされた後続の受信操作は、送信者のメッセージの終了を示します。 入力パラメーターとして、MSG_PARTIALは、サービス プロバイダーによってメッセージの一部のみが受信された場合でも、受信操作を完了する必要があることを示します。

重複した操作がすぐに完了すると、 LPWSPRecv は 0 の値を返し、 lpNumberOfBytesRecvd パラメーターは受信したバイト数で更新され、 lpFlags パラメーターが指すフラグ ビットも更新されます。 重複した操作が正常に開始され、後で完了する場合、 LPWSPRecv はSOCKET_ERRORを返し、エラー コード WSA_IO_PENDINGを示します。 この場合、 lpNumberOfBytesRecvdlpFlags は更新されません。 重複した操作が完了すると、転送されるデータの量は、完了ルーチンの cbTransferred パラメーター (指定されている場合) または LPWSPGetOverlappedResultlpcbTransfer パラメーターを使用して示されます。 フラグ値は、完了ルーチンの dwFlags パラメーターを使用するか、WSAGetOverlappedResultlpdwFlags パラメーターを調べることによって取得されます。

プロバイダーは、前の LPWSPRecv、LPWSPRecvFromLPWSPSend、LPWSPSendTo 関数の完了ルーチン内からこの関数を呼び出せるようにする必要があります。 ただし、特定のソケットでは、I/O 完了ルーチンを入れ子にすることはできません。 これにより、時間の影響を受けるデータ転送を、プリエンプティブ コンテキスト内で完全に実行できます。

lpOverlapped パラメーターは、重複する操作の間有効である必要があります。 複数の I/O 操作が同時に未処理の場合は、それぞれが個別の重複した構造を参照する必要があります。 WSAOverlapped 構造体は、独自の参照ページで定義されます。

lpCompletionRoutine パラメーターが null の場合、有効なイベント オブジェクト ハンドルが含まれている場合、重複した操作が完了すると、サービス プロバイダーは lpOverlappedhEvent メンバーに通知します。 Windows ソケット SPI クライアントは、 LPWSPGetOverlappedResult を使用して、イベント オブジェクトを待機またはポーリングできます。

lpCompletionRoutine が null でない場合、hEvent メンバーは無視され、Windows ソケット SPI クライアントがコンテキスト情報を完了ルーチンに渡すために使用できます。 null lpCompletionRoutine を渡し、その後、同じ重複した I/O 要求に対して WSAGetOverlappedResult を呼び出すクライアントでは、WSAGetOverlappedResult の呼び出しに対して fWait パラメーターを TRUE に設定することはできません。 この場合、 hEvent メンバーの使用は未定義であり、 hEvent メンバーを待機しようとすると予測できない結果が生成されます。

サービス プロバイダーは、重複した操作が完了したときに、クライアント指定完了ルーチンの呼び出しを手配する必要があります。 完了ルーチンは、重複した操作を開始したのと同じスレッドのコンテキストで実行する必要があるため、サービス プロバイダーから直接呼び出すことはできません。 Ws2_32.dll は、完了ルーチンの呼び出しを容易にする非同期プロシージャ 呼び出し (APC) メカニズムを提供します。

サービス プロバイダーは、重複した操作を開始するために使用された WPUQueueApc を呼び出すことによって、適切なスレッドとプロセス コンテキストで実行される関数を配置します。 この関数は、重複した操作を開始するために使用されたスレッドとプロセスとは異なるコンテキストであっても、任意のプロセスとスレッド コンテキストから呼び出すことができます。

WPUQueueApc は、入力パラメーターとして WSATHREADID 構造体へのポインター ( lpThreadId 入力パラメーターを介してプロバイダーに提供)、呼び出される APC 関数へのポインター、および後で APC 関数に渡されるコンテキスト値を受け取ります。 使用できるコンテキスト値は 1 つだけであるため、APC 関数自体をクライアント指定完了ルーチンにすることはできません。 サービス プロバイダーは、代わりに、指定されたコンテキスト値を使用して重複する操作に必要な結果情報にアクセスし、クライアント指定完了ルーチンを呼び出す独自の APC 関数へのポインターを指定する必要があります。

クライアント提供の完了ルーチンのプロトタイプは次のとおりです。

void CALLBACK 
CompletionRoutine(  
  IN DWORD           dwError, 
  IN DWORD           cbTransferred, 
  IN LPWSAOVERLAPPED lpOverlapped, 
  IN DWORD           dwFlags 
);

CompletionRoutine パラメーターは、クライアント指定の関数名のプレースホルダーです。 dwError はlpOverlapped で示されているように、重複する操作の完了状態を指定します。 cbTransferred パラメーターは、受信したバイト数を指定します。 dwFlags には、 受信操作がすぐに完了した場合に lpFlags に表示される情報が含まれます。 この関数は値を返しません。

完了ルーチンは任意の順序で呼び出すことができますが、重複する操作が完了した順序は必ずしも同じではありません。 ただし、ポストされたバッファーは、指定された順序と同じ順序で入力することが保証されます。

注意

特定のスレッドによって開始されたすべての I/O は、そのスレッドが終了すると取り消されます。 重複するソケットの場合、保留中の非同期操作は、操作が完了する前にスレッドが閉じられた場合に失敗する可能性があります。 詳細については、「 ExitThread 」を参照してください。

要件

要件
サポートされている最小のクライアント Windows 10 ビルド 20348
サポートされている最小のサーバー Windows 10 ビルド 20348
Header ws2spi.h

こちらもご覧ください

WPUCloseEvent

WPUCreateEvent

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket