TransmitFile()
TransmitFile()
起了个大早,赶了个晚集.。
习惯自己写协议来控制文件的传输,我就在想:是否Windows API直接搞定此问题?
某日,我们Aglty的苗同学说,有啊,Winsock可以直接传文件的啊。
惊奇,哪个API?苗说屈晓得,问屈,屈帮俺搜了下,答曰:TransmitFile(),
如获至宝啊…
话说昨晚在七杯茶我们团队喝茶扯淡完毕后,回来开始用TransmitFile()写文件传输,MSDN看了下,是这么说的:
The TransmitFile function transmits
file data over a connected socket handle. This function uses the operating
system's cache manager to retrieve the file data, and provides high-performance
file data transfer over sockets.
Note This
function is a Microsoft-specific extension to the Windows Sockets
specification.
BOOL TransmitFile(
SOCKET hSocket,
HANDLE hFile,
DWORD nNumberOfBytesToWrite,
DWORD nNumberOfBytesPerSend,
LPOVERLAPPED lpOverlapped,
LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
DWORD dwFlags
);
有几个参数比较有意思,例如:
nNumberOfBytesPerSend
The size, in bytes,
of each block of data sent in each send operation. This parameter is used by
Windows' sockets layer to determine the block size for send operations. To
select the default send size, set this parameter to zero.
The nNumberOfBytesPerSend
parameter is useful for protocols that have limitations on the size of individual
send requests.
分片,和我想法一致,赞一个..
lpTransmitBuffers
A pointer to a TRANSMIT_FILE_BUFFERS
data structure that contains pointers to data to send before and after the file data is sent. This parameter
should be set to a NULL pointer if you want to transmit only the file data.
这个参数超赞啊,刚好和我的协议吻合,我用可变协议写的,刚好放个协议头进去。
发现确实是省去了自己控制文件句柄,然后计算长度等等问题了,大致写了下,结果一直出错一直出错,我晕啊,为何协议头每次都不见了?
囧的晚上睡不着觉,今天6点就起来继续debug,算是这学期起的比较早的一次了..
10点终于解决,就是上面那句红字的问题…
before
and after the file data is sent.
the file data is sent ,我想当然的以为是NumberOfBytesPerSend
is sent了..
如果自己的协议控制的话..貌似昨晚就写完了吧..没办法..。
测试发现,用TransmitFile()
传40多MB的文件没出现异常,由于是本机地址测试,速度和把一个文件从C盘移到D盘差不多..。
写到最后,发现persend对我来说也没啥子用了…因为我是根据文件总长度用异步传输recv()的,和直接send()没啥子优势..。
我还发现,慢的不是winsock,是算法,例如屏幕传输..。
总之,在合适的地方用合适的API。