Win32 API 日本語リファレンス
ホーム › Networking.WinSock › LPFN_TRANSMITFILE

LPFN_TRANSMITFILE

コールバック

シグネチャ

BOOL LPFN_TRANSMITFILE(
    SOCKET hSocket,
    HANDLE hFile,
    DWORD nNumberOfBytesToWrite,
    DWORD nNumberOfBytesPerSend,
    OVERLAPPED* lpOverlapped,
    TRANSMIT_FILE_BUFFERS* lpTransmitBuffers,
    DWORD dwReserved
);

パラメーター

フィールド型説明
hSocketSOCKET接続済みソケットのハンドルです。 TransmitFile 関数は、このソケット経由でファイルデータを送信します。hSocket パラメーターに指定するソケットは、SOCK_STREAM、SOCK_SEQPACKET、または SOCK_RDM 型のコネクション指向ソケットである必要があります。
hFileHANDLE

TransmitFile 関数が送信する、オープン済みファイルのハンドルです。オペレーティングシステムはファイルデータを順次読み取るため、FILE_FLAG_SEQUENTIAL_SCAN を指定してハンドルを開くとキャッシュの性能を向上できます。

hFile パラメーターは省略可能です。hFile パラメーターが NULL の場合、ヘッダーバッファーおよび末尾バッファーのデータのみが送信されます。ソケットの切断や再利用といった追加の動作は、dwFlags パラメーターの指定に従って実行されます。

nNumberOfBytesToWriteDWORD

送信するファイル内のバイト数です。 TransmitFile 関数は、指定されたバイト数を送信した時点、またはエラーが発生した時点のいずれか早い方で完了します。

ファイル全体を送信するには、このパラメーターに 0 を設定します。

nNumberOfBytesPerSendDWORD

各送信操作で送信されるデータブロックのサイズ (バイト単位) です。このパラメーターは、Windows のソケット層が送信操作のブロックサイズを決定するために使用します。既定の送信サイズを選択するには、このパラメーターに 0 を設定します。

nNumberOfBytesPerSend パラメーターは、個々の送信要求のサイズに制限があるプロトコルで役立ちます。

lpOverlappedOVERLAPPED*

OVERLAPPED 構造体へのポインターです。ソケットハンドルがオーバーラップとして開かれている場合、オーバーラップ (非同期) I/O 操作を行うにはこのパラメーターを指定します。既定では、ソケットハンドルはオーバーラップとして開かれます。

OVERLAPPED 構造体の Offset メンバーと OffsetHigh メンバーを設定することで、lpOverlapped パラメーターによりファイルデータの転送を開始するファイル内の 64 ビットオフセットを指定できます。lpOverlapped が NULL ポインターの場合、データの送信は常にファイル内の現在のバイトオフセットから開始されます。

lpOverlapped が NULL でない場合、 TransmitFile が返る前にオーバーラップ I/O が完了しないことがあります。その場合、 TransmitFile 関数は FALSE を返し、WSAGetLastError は ERROR_IO_PENDING または WSA_IO_PENDING を返します。これにより、呼び出し元はファイル送信操作が完了するまでの間も処理を継続できます。Windows は、データ送信要求の完了時に、OVERLAPPED 構造体の hEvent メンバーで指定されたイベント、または hSocket で指定されたソケットをシグナル状態にします。

lpTransmitBuffersTRANSMIT_FILE_BUFFERS*TRANSMIT_FILE_BUFFERS データ構造体へのポインターです。この構造体には、ファイルデータの送信前および送信後に送るデータへのポインターが格納されます。ファイルデータのみを送信する場合は、このパラメーターに NULL ポインターを設定します。
dwReservedDWORD

TransmitFile 関数の呼び出しの動作を変更するために使用するフラグのセットです。dwFlags パラメーターには、Mswsock.h ヘッダーファイルで定義されている次のオプションの組み合わせを指定できます。

フラグ 意味
TF_DISCONNECT
すべてのファイルデータが送信用にキューへ入れられた後、トランスポートレベルの切断を開始します。
TF_REUSE_SOCKET
ソケットハンドルを再利用できるように準備します。このフラグは、TF_DISCONNECT も指定されている場合にのみ有効です。

TransmitFile 要求が完了すると、そのソケットハンドルを、接続の確立に以前使用した関数の呼び出し(AcceptEx や ConnectEx など) に渡すことができます。このような再利用は排他的です。たとえば、そのソケットに対して AcceptEx 関数を呼び出していた場合、再利用が許可されるのは以降の AcceptEx 関数の呼び出しに対してのみであり、以降の ConnectEx の呼び出しには許可されません。

Note ソケットレベルのファイル送信は、基盤となるトランスポートの動作に左右されます。たとえば TCP ソケットは TCP の TIME_WAIT 状態の影響を受けることがあり、その場合 TransmitFile の呼び出しが遅延します。
TF_USE_DEFAULT_WORKER
長時間の TransmitFile 要求の処理にシステムの既定のスレッドを使用するよう、Windows Sockets サービスプロバイダーに指示します。システムの既定のスレッドは、次のレジストリパラメーターを REG_DWORD として設定することで調整できます。

HKEY_LOCAL_MACHINE\CurrentControlSet\Services\AFD\Parameters\TransmitWorker

TF_USE_SYSTEM_THREAD
長時間の TransmitFile 要求の処理にシステムスレッドを使用するよう、Windows Sockets サービスプロバイダーに指示します。
TF_USE_KERNEL_APC
長時間の TransmitFile 要求の処理に、ワーカースレッドではなくカーネルの非同期プロシージャ呼び出し (APC) を使用するようドライバーに指示します。長時間の TransmitFile 要求とは、ファイルまたはキャッシュからの読み取りが 1 回では済まない要求のことです。したがって、該当するかどうかはファイルのサイズと指定された送信パケット長に依存します。

TF_USE_KERNEL_APC を使用すると、大幅な性能向上が得られる場合があります。ただし、可能性は低いものの、 TransmitFile を開始したコンテキストのスレッドが重い計算処理に使用されていることがあり、その場合は APC が起動できないことがあります。なお、Winsock のカーネルモードドライバーは通常のカーネル APC を使用します。これはスレッドが待機状態になるたびに起動するもので、ユーザーモードで開始されたアラート可能待機状態のときに起動するユーザーモード APC とは異なります。

TF_WRITE_BEHIND

TransmitFile 要求を保留せずに直ちに完了します。このフラグを指定して TransmitFile が成功した場合、データはシステムに受け入れられていますが、リモート側で確認応答されているとは限りません。この設定を TF_DISCONNECT フラグおよび TF_REUSE_SOCKET フラグと併用しないでください。

Note 送信するファイルがファイルシステムキャッシュに存在しない場合、要求は保留されます。

公式ドキュメント

TransmitFile 関数は、接続済みのソケットハンドル経由でファイルデータを送信します。この関数は、オペレーティングシステムのキャッシュマネージャーを使用してファイルデータを取得し、ソケット経由で高性能なファイルデータ転送を提供します。

Note この関数は、Windows Sockets 仕様に対する Microsoft 固有の拡張です。

戻り値

TransmitFile 関数が成功した場合、戻り値は TRUE です。それ以外の場合、戻り値は FALSE です。拡張エラー情報を取得するには、 WSAGetLastError を呼び出します。エラーコード WSA_IO_PENDING または ERROR_IO_PENDING は、オーバーラップ操作が正常に開始され、完了が後で通知されることを示します。それ以外のエラーコードは、オーバーラップ操作が正常に開始されず、完了通知も行われないことを示します。この場合、アプリケーションは ERROR_IO_PENDING と WSA_IO_PENDING のいずれも処理する必要があります。

戻り値 説明
WSAECONNABORTED
確立されていた接続が、ホストコンピューター上のソフトウェアによって中止されました。このエラーは、タイムアウトやその他の障害により仮想回線が終了した場合に返されます。
WSAECONNRESET
既存の接続が、リモートホストによって強制的に閉じられました。このエラーは、ストリームソケットにおいてリモート側が仮想回線をリセットした場合に返されます。そのソケットは使用できなくなるため、アプリケーションはソケットを閉じる必要があります。
WSAEFAULT
呼び出しでポインター引数を使用しようとした際に、システムが無効なポインターアドレスを検出しました。このエラーは、lpTransmitBuffers または lpOverlapped パラメーターの全体がユーザーアドレス空間の有効な領域に含まれていない場合に返されます。
WSAEINVAL
無効な引数が指定されました。このエラーは、hSocket パラメーターに SOCK_DGRAM 型または SOCK_RAW 型のソケットを指定した場合に返されます。また、dwFlags パラメーターに TF_REUSE_SOCKET フラグが設定されているにもかかわらず TF_DISCONNECT フラグが設定されていない場合にも返されます。さらに、lpOverlapped が指す OVERLAPPED 構造体で指定されたオフセットがファイル内に収まっていない場合にも返されます。加えて、nNumberOfBytesToWrite パラメーターに 2,147,483,646 (32 ビット整数の最大値から 1 を引いた値) を超える値を設定した場合にも返されます。
WSAENETDOWN
ソケット操作が停止したネットワークを検出しました。このエラーは、ネットワークサブシステムに障害が発生した場合に返されます。
WSAENETRESET
操作の実行中に keep-alive 動作が障害を検出したため、接続が切断されました。
WSAENOBUFS
システムに十分なバッファー領域がなかったか、キューが満杯であったため、ソケットに対する操作を実行できませんでした。このエラーは、Windows Sockets プロバイダーがバッファーのデッドロックを報告した場合にも返されます。
WSAENOTCONN
ソケットが接続されていないため、データの送信または受信の要求は許可されませんでした。
WSAENOTSOCK
ソケットではないものに対して操作が試行されました。このエラーは、hSocket パラメーターがソケットでない場合に返されます。
WSAESHUTDOWN
以前の shutdown 呼び出しによって、ソケットがその方向に対して既にシャットダウンされていたため、データの送信または受信の要求は許可されませんでした。このエラーは、ソケットが送信方向にシャットダウンされている場合に返されます。how パラメーターに SD_SEND または SD_BOTH を設定して shutdown 関数をソケットに対して呼び出した後は、そのソケットで TransmitFile を呼び出すことはできません。
WSANOTINITIALISED
アプリケーションが WSAStartup 関数を呼び出していないか、WSAStartup が失敗しました。TransmitFile 関数を使用する前に、 WSAStartup の呼び出しが成功している必要があります。
WSA_IO_PENDING
オーバーラップ I/O 操作が進行中です。この値は、オーバーラップ I/O 操作が正常に開始された場合に返され、完了が後で通知されることを示します。
WSA_OPERATION_ABORTED
スレッドの終了またはアプリケーションの要求により、I/O 操作が中止されました。このエラーは、ソケットのクローズ、 WSAIoctl における "SIO_FLUSH" コマンドの実行、またはオーバーラップ要求を開始したスレッドが操作完了前に終了したことにより、オーバーラップ操作が取り消された場合に返されます。
Note あるスレッドが開始したすべての I/O は、そのスレッドの終了時に取り消されます。オーバーラップソケットでは、非同期操作が完了する前にスレッドが終了すると、保留中の非同期操作が失敗することがあります。詳細については、ExitThread を参照してください。

解説(Remarks)

TransmitFile 関数は、オペレーティングシステムのキャッシュマネージャーを使用してファイルデータを取得し、ソケット経由で高性能なファイルデータ転送を提供します。

TransmitFile 関数がサポートするのは、SOCK_STREAM、SOCK_SEQPACKET、SOCK_RDM 型のコネクション指向ソケットのみです。SOCK_DGRAM 型および SOCK_RAW 型のソケットはサポートされません。SOCK_DGRAM 型のソケットでは、TransmitPackets 関数を使用できます。

TransmitFile 関数の 1 回の呼び出しで送信できる最大バイト数は、2,147,483,646 (32 ビット整数の最大値から 1 を引いた値) です。1 回の呼び出しで送信できる最大バイト数には、lpTransmitBuffers パラメーターが指すファイルデータの前後に送信されるデータと、送信するファイルデータの長さとして nNumberOfBytesToWrite パラメーターに指定した値の両方が含まれます。アプリケーションが 2,147,483,646 バイトを超えるファイルを送信する必要がある場合は、1 回あたりの転送が 2,147,483,646 バイトを超えないようにして TransmitFile 関数を複数回呼び出します。2,147,483,646 バイトを超えるファイルに対して nNumberOfBytesToWrite パラメーターに 0 を設定した場合も失敗します。この場合、TransmitFile 関数は送信するバイト数としてファイルのサイズを使用するためです。

Note TransmitFile 関数の関数ポインターは、SIO_GET_EXTENSION_FUNCTION_POINTER オペコードを指定して WSAIoctl 関数を呼び出し、実行時に取得する必要があります。WSAIoctl 関数に渡す入力バッファーには、TransmitFile 拡張関数を識別する値を持つグローバル一意識別子 (GUID) である WSAID_TRANSMITFILE を格納する必要があります。成功した場合、WSAIoctl 関数が返す出力には TransmitFile 関数へのポインターが格納されます。WSAID_TRANSMITFILE GUID は Mswsock.h ヘッダーファイルで定義されています。
Note TransmitFile は、独自のバッファリングを行うトランスポートでは機能しません。ADSP など、TDI_SERVICE_INTERNAL_BUFFERING フラグが設定されているトランスポートは、独自のバッファリングを行います。 TransmitFile は、ファイルキャッシュから直接データを送信することで性能上の利点を得ているためです。特定の接続でバッファー領域を使い果たすトランスポートは TransmitFile では扱われず、その接続でバッファー領域を使い果たした結果、 TransmitFile は STATUS_DEVICE_NOT_READY を返します。
TransmitFile 関数は、主に高性能なサーバーアプリケーション (Web サーバーや ftp サーバーなど) で使用するために Winsock に追加されました。

Windows のワークステーション版およびクライアント版では、システム上で同時に実行できる TransmitFile 操作の数を最大 2 つに制限することで、メモリとリソースの使用量が最小になるように TransmitFile 関数を最適化しています。Windows Vista、Windows XP、 Windows 2000 Professional、および Windows NT Workstation 3.51 以降では、同時に処理される未完了の TransmitFile 要求は 2 つまでであり、3 つ目の要求は先行する要求のいずれかが完了するまで待機します。

Windows のサーバー版では、 TransmitFile 関数は高性能になるように最適化されています。サーバー版では、システム上で同時に実行できる TransmitFile 操作の数に既定の制限はありません。Windows のサーバー版で TransmitFile を使用すると、より良い性能が期待できます。Windows のサーバー版では、次の REG_DWORD のレジストリエントリを作成して値を設定することで、同時に実行できる TransmitFile 操作の最大数に制限を設けることもできます。

HKEY_LOCAL_MACHINE\CurrentControlSet\Services\AFD\Parameters\MaxActiveTransmitFileCount

TCP ソケット (プロトコルが IPPROTO_TCP) に対して TF_DISCONNECT フラグと TF_REUSE_SOCKET フラグの両方を指定して TransmitFile 関数を呼び出した場合、次の 2 つの条件が満たされるまで呼び出しは完了しません。

lpOverlapped パラメーターに NULL を設定して TransmitFile 関数を呼び出した場合、この操作は同期 I/O として実行されます。この場合、関数はファイルの送信が完了するまで戻りません。

Windows Phone 8: この関数は、Windows Phone 8 以降の Windows Phone ストアアプリでサポートされます。

Windows 8.1 および Windows Server 2012 R2: この関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストアアプリでサポートされます。

QoS に関する注意

TransmitFile 関数では、ファイルの送信後にソケットを「切断済みで再利用可能」な状態に戻す 2 つのフラグ、TF_DISCONNECT と TF_REUSE_SOCKET を設定できます。これらのフラグは、QoS (サービス品質) が要求されているソケットでは使用しないでください。サービスプロバイダーが、ファイル転送の完了前にそのソケットに関連付けられた QoS を直ちに削除する可能性があるためです。QoS を有効にしたソケットでは、これらのフラグに頼るのではなく、ファイル転送の完了時に closesocket 関数を単純に呼び出すのが最善です。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)