一次调用 TransmitFile 函数可以传输的最大字节数为 2,147,483,646,即 32 位整数减 1 的最大值。在一次调用中发送的最大字节数包括之前或之后发送的任何数据lpTransmitBuffers 参数指向的文件数据加上 nNumberOfBytesToWrite 参数中指定的值作为要发送的文件数据的长度。如果应用程序需要传输大于 2,147,483,646 字节的文件,则可以多次调用 TransmitFile 函数,每次调用传输不超过 2,147,483,646 字节。对于大于 2,147,483,646 字节的文件,将 nNumberOfBytesToWrite 参数设置为零也会失败,因为在这种情况下,TransmitFile 函数将使用文件的大小作为要传输的字节数的值。
好吧。使用 TransmitFile发送一个大小为2*2,147,483,646 bytes
(~ 4 GiB) 的文件必须至少分成两部分(例如,两次调用 TransmitFile 中的 2 GiB + 2 GiB)。但是,如何做到这一点,同时最好同时保持底层 TCP 连接处于活动状态?
当文件的大小确实 <=2,147,483,646 字节时,可以只写:
HANDLE fh = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
TransmitFile(SOCK_STREAM_socket, fh, 0, 0, NULL, NULL, TF_DISCONNECT);
让 Windows 处理所有较低级别的东西(缓存、将数据分块以实现高效传输等。但是,与类似的 Linux sendfile()系统调用不同,调用中没有立即明显的偏移参数(尽管第五个参数,LPOVERLAPPED lpOverlapped
可能正是我正在寻找的东西)。我想我可以一起破解一些东西,但我也在寻找一个真正了解这些东西的人的优雅、良好实践的 Win32 解决方案。
通过设置 OVERLAPPED 结构的 Offset 和 OffsetHigh 成员,您可以使用 lpOverlapped 参数指定文件内开始文件数据传输的 64 位偏移量。如果 lpOverlapped 是一个 NULL 指针,数据的传输总是从文件中的当前字节偏移开始。
那么,由于缺乏网络上现成的最小示例,完成这样的任务需要哪些调用?