gpt4 book ai didi

sockets - 如何使用 Win32 TransmitFile() 传输大于 2,147,483,646 字节 (~2 GiB) 的文件?

转载 作者:行者123 更新时间:2023-12-02 10:56:45 24 4
gpt4 key购买 nike

引自MSDN entry for TransmitFile :

The maximum number of bytes that can be transmitted using a single call to the TransmitFile function is 2,147,483,646, the maximum value for a 32-bit integer minus 1. The maximum number of bytes to send in a single call includes any data sent before or after the file data pointed to by the lpTransmitBuffers parameter plus the value specified in the nNumberOfBytesToWrite parameter for the length of file data to send. If an application needs to transmit a file larger than 2,147,483,646 bytes, then multiple calls to the TransmitFile function can be used with each call transferring no more than 2,147,483,646 bytes. Setting the nNumberOfBytesToWrite parameter to zero for a file larger than 2,147,483,646 bytes will also fail since in this case the TransmitFile function will use the size of the file as the value for the number of bytes to transmit.

好吧。使用 TransmitFile 发送大小为 2*2,147,483,646 字节 (~ 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解决方案,来自实际上的人知道这些东西。

You can use the lpOverlapped parameter to specify a 64-bit offset within the file at which to start the file data transfer by setting the Offset and OffsetHigh member of the OVERLAPPED structure. If lpOverlapped is a NULL pointer, the transmission of data always starts at the current byte offset in the file.

那么,由于网络上缺乏可用的最小示例,完成这样的任务需要哪些调用?

最佳答案

根据评论设法弄清楚了。

因此,如果 LPOVERLAPPED lpOverlapped 是空指针,则调用会在文件的当前文件偏移处开始传输(与 Linux sendfile() 非常相似) 系统调用及其 off_t *offset 参数)。该偏移量(指针)可以使用 SetFilePointerEx 进行操作,因此可以编写:

#define TRANSMITFILE_MAX ((2<<30) - 1)

LARGE_INTEGER total_bytes;
memset(&total_bytes, 0, sizeof(total_bytes));

while (total_bytes < filesize) {
DWORD bytes = MIN(filesize-total_bytes, TRANSMITFILE_MAX);
if (!TransmitFile(SOCK_STREAM_socket, fh, bytes, 0, NULL, NULL, 0))
{ /* error handling */ }

total_bytes.HighPart += bytes;
SetFilePointerEx(fh, total_bytes, NULL, FILE_BEGIN);
}

closesocket(SOCK_STREAM_socket);

完成任务。在我看来,不是很优雅,但它确实有效。

关于sockets - 如何使用 Win32 TransmitFile() 传输大于 2,147,483,646 字节 (~2 GiB) 的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18240501/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com