LPWSPSENDTO コールバック関数 (ws2spi.h)
LPWSPSendTo 関数は、重複した I/O を使用して特定の宛先にデータを送信します。
構文
LPWSPSENDTO Lpwspsendto;
int Lpwspsendto(
[in] SOCKET s,
[in] LPWSABUF lpBuffers,
[in] DWORD dwBufferCount,
[out] LPDWORD lpNumberOfBytesSent,
[in] DWORD dwFlags,
[in] const sockaddr *lpTo,
[in] int iTolen,
[in] LPWSAOVERLAPPED lpOverlapped,
[in] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
[in] LPWSATHREADID lpThreadId,
[out] LPINT lpErrno
)
{...}
パラメーター
[in] s
ソケットを識別する記述子。
[in] lpBuffers
WSABUF 構造体の配列へのポインター。 各 WSABUF 構造体には、バッファーへのポインターとバッファーの長さ (バイト単位) が含まれます。 Winsock アプリケーションの場合、 LPWSPSendTo 関数が呼び出されると、システムはこれらのバッファーを所有し、アプリケーションがそれらにアクセスできない可能性があります。 各 WSABUF 構造体で参照されるデータ バッファーはシステムによって所有されており、アプリケーションが呼び出しの有効期間にわたってアクセスできない場合があります。
[in] dwBufferCount
lpBuffers 配列内の WSABUF 構造体の数。
[out] lpNumberOfBytesSent
この呼び出しによって送信されたバイト数へのポインター。
[in] dwFlags
呼び出しの方法を指定するフラグのセット。
[in] lpTo
sockaddr 構造体内のターゲット ソケットのアドレスへの省略可能なポインター。
[in] iTolen
lpTo パラメーターが指すアドレスのサイズ (バイト単位)。
[in] lpOverlapped
WSAOverlapped 構造体へのポインター (オーバーラップされていないソケットの場合は無視されます)。
[in] lpCompletionRoutine
種類: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
送信操作が完了したときに呼び出される完了ルーチンへのポインター (オーバーラップされていないソケットの場合は無視されます)。
[in] lpThreadId
WPUQueueApc への後続の呼び出しでプロバイダーによって使用される WSATHREADID 構造体へのポインター。 プロバイダーは、WPUQueueApc 関数が返されるまで、参照先の WSATHREADID 構造体 (同じへのポインターではない) を格納する必要があります。
[out] lpErrno
エラー コードへのポインター。
戻り値
エラーが発生せず、受信操作がすぐに完了した場合、 LPWSPSendTo は 0 を 返します。 この場合、完了ルーチン (指定されている場合) は既にキューに登録されていることに注意してください。 それ以外の場合は、SOCKET_ERRORの値が返され、 lpErrno で特定のエラー コードを使用できます。 エラー コード WSA_IO_PENDING は、重複した操作が正常に開始され、その完了が後で示されることを示します。 その他のエラー コードは、重複する操作が開始されておらず、完了の兆候が発生しなかったことを示します。
エラー コード | 意味 |
---|---|
ネットワーク サブシステムが失敗しました。 | |
要求されたアドレスはブロードキャスト アドレスですが、適切なフラグが設定されていません。 | |
(ブロッキング) 呼び出しは LPWSPCancelBlockingCall を介して取り消されました。 | |
Windows ソケット呼び出しのブロックが進行中であるか、サービス プロバイダーがコールバック関数を処理しています。 | |
lpBuffers パラメーターまたは lpTo パラメーターがユーザー アドレス空間に含まれていないか、lpTo パラメーターが小さすぎます。 | |
操作の実行中にキープ アライブ動作によってエラーが検出されたため、接続が切断されました。 | |
Windows ソケット プロバイダーは、バッファー のデッドロックを報告します。 | |
ソケットが接続されていません (接続指向のソケットのみ)。 | |
記述子はソケットではありません。 | |
MSG_OOBが指定されましたが、ソケットが型SOCK_STREAMなどのストリーム スタイルではなく、このソケットに関連付けられている通信ドメインでは OOB データがサポートされていない、MSG_PARTIALがサポートされていない、またはソケットが一方向であり、受信操作のみをサポートしています。 | |
ソケットがシャットダウンされました。LPWSPShutdown が SD_SEND または SD_BOTH に設定された方法で呼び出された後、ソケットで LPWSPSendTo を使用することはできません。 | |
Windows NT: 重複するソケット: 未解決の重複した I/O 要求が多すぎます。オーバーラップされていないソケット: ソケットは非ブロッキングとしてマークされ、送信操作をすぐに完了することはできません。 | |
ソケットはメッセージ指向であり、メッセージは基になるトランスポートでサポートされる最大値を超えています。 | |
ソケットが LPWSPBind にバインドされていないか、またはソケットが重複するフラグで作成されていません。 | |
タイムアウトまたはその他の障害が原因で仮想回線が終了しました。 | |
仮想回線がリモート側でリセットされました。 | |
リモート アドレスが有効なアドレスではありません (たとえば、ADDR_ANY)。 | |
指定されたファミリーのアドレスをこのソケットと共に使用することはできません。 | |
宛先アドレスが必要です。 | |
現在このホストからネットワークには到達できません。 | |
ソケットのクローズ、または LPWSPIoctl での SIO_FLUSH コマンドの実行により、重複する操作が取り消されました。 |
解説
LPWSPSendTo 関数は、通常、lpToパラメーターで識別される特定のピア ソケットに 1 つ以上のバッファーに含まれるデータグラムを送信するために、 によって指定されたコネクションレス ソケットで使用されます。 コネクションレス ソケットが LPWSPConnect 関数を使用して特定のアドレスに以前に接続されていた場合でも、 lpTo はその特定のデータグラムの宛先アドレスのみをオーバーライドします。 接続指向ソケットでは、 lpTo パラメーターと iToLen パラメーターは無視されます。この場合、 LPWSPSendTo 関数は LPWSPSend と同じです。
重複するソケット (フラグがWSA_FLAG_OVERLAPPEDされた LPWSPSocket を使用して作成) の場合、 lpOverlapped と lpCompletionRoutine の両方が NULL でない限り、重複した I/O を使用して発生します。この場合、ソケットはオーバーラップされていないソケットとして扱われます。 指定されたバッファーがトランスポートによって使用されると、完了表示 (完了ルーチンの呼び出しまたはイベント オブジェクトの設定) が発生します。 操作がすぐに完了しない場合は、完了ルーチンまたは LPWSPGetOverlappedResult を使用して最終的な完了状態が取得されます。
オーバーラップされていないソケットの場合、パラメーター lpOverlapped、 lpCompletionRoutine、 lpThreadId は無視され、 LPWSPSendTo は 通常の同期セマンティクスを採用します。 データは、指定されたバッファーからトランスポートのバッファーにコピーされます。 ソケットが非ブロッキングでストリーム指向で、トランスポートのバッファーに十分な領域がない場合、 LPWSPSendTo は、使用された Windows ソケット SPI クライアントのバッファーの一部のみを使用して を返します。 同じバッファー状況とブロッキング ソケットを考えると、 LPWSPSendTo は、Windows ソケット SPI クライアントのすべてのバッファー コンテンツが使用されるまでブロックします。
lpBuffers パラメーターが指す WSABUF 構造体の配列は一時的なものです。 この操作が重複して完了した場合、この呼び出しから戻る前にこれらの WSABUF 構造体をキャプチャするのはサービス プロバイダーの責任です。 これにより、アプリケーションはスタック ベースの WSABUF 配列を構築できます。
メッセージ指向ソケットの場合は、ソケット オプション SO_MAX_MSG_SIZEの値を取得することで取得できる、基になるトランスポートの最大メッセージ サイズを超えないように注意する必要があります。 データが長すぎて、基になるプロトコルをアトミックに通過できない場合は、 エラー WSAEMSGSIZE が返され、データは送信されません。
LPWSPSendTo の正常な完了は、データが正常に配信されたことを示すものではありません。
iFlags パラメーターを使用すると、関連付けられたソケットに指定されたオプションを超えて、関数呼び出しの動作に影響を与えることができます。 つまり、この関数のセマンティクスは、ソケット オプションと dwFlags パラメーターによって決定されます。 後者は、次のいずれかの値を持つビットごとの OR 演算子を使用して構築されます。
値 | 説明 |
---|---|
MSG_DONTROUTE | データをルーティングの対象にしないことを指定します。 Windows ソケット サービス プロバイダーは、このフラグを無視することを選択できます。 |
MSG_OOB | OOB データを送信します (SOCK_STREAM などのストリーム スタイルのソケットのみ)。 |
MSG_PARTIAL | lpBuffers に部分的なメッセージのみが含まれていることを指定します。 エラー コード WSAEOPNOTSUPP は、部分的なメッセージ転送をサポートしていないトランスポートによって返されることに注意してください。 |
重複した操作が直ちに完了すると、 LPWSPSendTo は 0 の値を返し、 lpNumberOfBytesSent パラメーターは送信されたバイト数で更新されます。 重複した操作が正常に開始され、後で完了する場合、 LPWSPSendTo はSOCKET_ERRORを返し、エラー コードWSA_IO_PENDINGを示します。 この場合、 lpNumberOfBytesSent は更新されません。 重複する操作が完了すると、転送されるデータの量は、完了ルーチンの cbTransferred パラメーター (指定されている場合) または LPWSPGetOverlappedResult の lpcbTransfer パラメーターを使用して示されます。
プロバイダーは、以前の LPWSPRecv、LPWSPRecvFrom、LPWSPSend または LPWSPSendTo 関数の完了ルーチン内からこの関数を呼び出せるようにする必要があります。 ただし、特定のソケットでは、I/O 完了ルーチンを入れ子にすることはできません。 これにより、時間の影響を受けやすいデータ転送は、プリエンプティブ コンテキスト内で完全に行われます。
lpOverlapped パラメーターは、重複する操作の間有効である必要があります。 複数の I/O 操作が同時に未処理の場合は、それぞれが個別の重複した構造体を参照する必要があります。 WSAOverlapped 構造体は、独自の参照ページで定義されています。
lpCompletionRoutine パラメーターが null の場合、有効なイベント オブジェクト ハンドルが含まれている場合、重複した操作が完了すると、サービス プロバイダーは lpOverlapped の hEvent メンバーに通知します。 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 値は 0 になります。 この関数は値を返しません。
完了ルーチンは任意の順序で呼び出すことができますが、重複する操作が完了した順序と必ずしも同じ順序であるとは限りません。 ただし、サービス プロバイダーは、ポストされたバッファーが提供されたのと同じ順序で送信されることをクライアントに保証します。
注意
特定のスレッドによって開始されたすべての I/O は、そのスレッドが終了すると取り消されます。 重複するソケットの場合、操作が完了する前にスレッドが閉じられた場合、保留中の非同期操作が失敗する可能性があります。 詳細については、「 ExitThread 」を参照してください。
要件
サポートされている最小のクライアント | Windows 2000 Professional [デスクトップ アプリのみ] |
サポートされている最小のサーバー | Windows 2000 Server [デスクトップ アプリのみ] |
Header | ws2spi.h |