次の方法で共有


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

LPWSPRecvFrom 関数は、データグラムを受け取り、ソース アドレスを格納します。

構文

LPWSPRECVFROM Lpwsprecvfrom;

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

パラメーター

[in] s

ソケットを識別する記述子。

[in, out] lpBuffers

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

[in] dwBufferCount

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

[out] lpNumberOfBytesRecvd

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

[in, out] lpFlags

フラグへのポインター。

[out] lpFrom

重複する操作の完了時にソース アドレスを保持する sockaddr 構造体内のバッファーへの省略可能なポインター。

[in, out] lpFromlen

lpFrom バッファーのサイズへのポインター (バイト単位) は、lpFrom が指定されている場合にのみ必要です。

[in] lpOverlapped

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

[in] lpCompletionRoutine

種類: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

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

\\[in\\] lpThreadId

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

[in, out] lpErrno

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

戻り値

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

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

解説

LPWSPRecvFrom 関数は、主に s で指定されたコネクションレス ソケットで使用されます。ソケットは接続できません。 ソケットのローカル アドレスがわかっている必要があります。 これは、 LPWSPBind を介して明示的に行うか、 LPWSPSendTo または LPWSPJoinLeaf を介して暗黙的に行うことができます。

重複するソケットの場合、この関数は、受信データが (接続されている可能性がある) ソケットで使用可能になったときに受信データが配置される 1 つ以上のバッファーをポストするために使用されます。その後、クライアント指定の完了指示 (完了ルーチンの呼び出しまたはイベント オブジェクトの設定) が発生します。 操作がすぐに完了しない場合は、完了ルーチンまたは LPWSPGetOverlappedResult を介して最終的な完了状態が取得されます。 また、lpFrom と lpFromlen が指す値は、完了が示されるまで更新されないことに注意してください。 アプリケーションでは、これらの値が更新されるまで、これらの値を使用したり、応答したりすることはできません。したがって、クライアントでは、これらのパラメーターに自動 (つまりスタック ベース) 変数を使用しないでください。

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

オーバーラップされていないソケットの場合、 lpOverlappedlpCompletionRoutine、および lpThreadId パラメーターは無視されます。 トランスポートによって既に受信およびバッファリングされているデータは、指定されたユーザー バッファーにコピーされます。 トランスポートによって現在受信およびバッファリングされているデータがないブロッキング ソケットの場合、呼び出しは、 LPWSPRecv に割り当てられたブロッキング セマンティクスに従ってデータが受信されるまでブロックされます。

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

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

コネクションレス・ソケット・タイプの場合、データの発信元のアドレスは lpFrom が指すバッファーにコピーされます。 入力時に、 lpFromlen が指す値はこのバッファーのサイズに初期化され、完了時に変更され、そこに格納されているアドレスの実際のサイズが示されます。

前述のように、重複したソケットについては、重複した I/O が完了するまで lpFrom パラメーターと lpFromlen パラメーターは更新されません。 したがって、これらのパラメーターによって指されるメモリは、サービス プロバイダーが使用でき、Windows ソケット SPI クライアントのスタック フレームに割り当てることができない必要があります。 接続指向ソケットの 場合、lpFrom パラメーターと lpFromlen パラメーターは無視されます。

バイト ストリーム スタイルのソケット (たとえば、「SOCK_STREAM」) の場合、バッファーがいっぱいになるまで、接続が閉じられるか、内部的にバッファーに格納されたデータが使い果たされるまで、受信データがバッファーに配置されます。 受信データがすべてのバッファーを満たすかどうかに関係なく、重複するソケットに対して完了の兆候が発生します。

メッセージ指向ソケットの場合、指定されたバッファーに 1 つの受信メッセージが配置され、指定されたバッファーの合計サイズまでになり、重複したソケットに対して完了の兆候が発生します。 メッセージが指定されたバッファーより大きい場合、バッファーにはメッセージの最初の部分が入力されます。 MSG_PARTIAL機能がサービス プロバイダーによってサポートされている場合、ソケットの lpFlags にMSG_PARTIAL フラグが設定され、後続の受信操作によってメッセージの残りの部分が取得されます。 MSG_PARTIALがサポートされていないが、プロトコルが信頼できる場合、 LPWSPRecvFrom はエラー WSAEMSGSIZE を生成し、より大きなバッファーを持つ後続の受信操作を使用してメッセージ全体を取得できます。 それ以外の場合 (つまり、プロトコルは信頼性が低く、MSG_PARTIALをサポートしていません)、余分なデータが失われ、 LPWSPRecvFrom によってエラー WSAEMSGSIZE が生成されます。

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

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

 

 

メッセージ指向ソケットの場合、部分的なメッセージを受信した場合、 lpFlags パラメーターにMSG_PARTIALビットが設定されます。 完全なメッセージを受信すると、 lpFlags でMSG_PARTIALがクリアされます。 遅延完了の場合、 lpFlags が指す値は更新されません。 完了が示されたら、Windows ソケット SPI クライアントは LPWSPGetOverlappedResult を呼び出し、 lpdwFlags パラメーターによって指されるフラグを調べる必要があります。

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

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

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

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

lpCompletionRoutine が null でない場合、hEvent メンバーは無視され、Windows ソケット SPI クライアントがコンテキスト情報を完了ルーチンに渡すために使用できます。 サービス プロバイダーは、重複した操作が完了したときに、クライアント指定完了ルーチンの呼び出しを手配する必要があります。 完了ルーチンは、重複した操作を開始したのと同じスレッドのコンテキストで実行する必要があるため、サービス プロバイダーから直接呼び出すことはできません。 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 に表示される情報が含まれます。 この関数は値を返しません。

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

Note

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

要件

   
サポートされている最小のクライアント Windows 2000 Professional [デスクトップ アプリのみ]
サポートされている最小のサーバー Windows 2000 Server [デスクトップ アプリのみ]
Header ws2spi.h

関連項目

WPUQueueApc

LPWSPGetOverlappedResult

LPWSPSocket