在工作中为了高效的上传下载文件,我使用到了TransmitFile这个API,它允许在套接字连接上发送一个打开的文件。这使得应用程序可以避免亲自打开文件,重复地在文件执行读入操作,再将读入的那块数据写入套接字。
在使用过程中需要服务器和客户端两个部分,服务器运行起来后监听socket端口,当有套接字链接进入后便开始读取字节流,需要注意的是TansmitFile的参数:
【windows工作相关|windows下使用TransmitFile传输文件并接收的方法】BOOL PASCAL TransmitFile(
SOCKET hSocket,
HANDLE hFile,
DWORD nNumberOfBytesToWrite,
DWORD nNumberOfBytesPerSend,
LPOVERLAPPED lpOverlapped,
LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
DWORD dwFlags
);
hSocket一个连接的套接字句柄。函数将文件数据写向这个套接字。其必须是面向连接(TCP)的SOCKET。
hFile,如果为NULL, lpTransmitBuffers将被传输hFile已打开的文件句柄。
nNumberOfBytesToWrite :要传送的字节数。0值表示传送整个文件。发生错误时,以已发送数据为准。
nNumberOfBytesPerSend :每次传送的数据块的大小。0值表示使用SOCKET LAYER的默认值。
lpOverlapped :指向OVERLAPPED结构的指针。如果hSocket以打开重叠(默认),可指定这个参数,以实现一个重叠IO操作(异步)。NULL值表示不开启overlapped(重叠) I/O模式。
lpTransmitBuffers :指向TRANSMIT_FILE_BUFFERS结构指针。NULL值表示仅仅传输文件。
dwFlags :用于修改TransmitFile函数调用行为的标识.
注意:TransmitFile在传输文件时是会粘包的,所以如果不能发送确定的长度,最好使用到lpTransmitBuffers这个参数,用它来携带文件的长度或者其他信息,它会在服务器接收时最先接收到,用这个参数如果传递tlv格式的结构体的话,也是要处理粘包的问题的。