#include <WinInet.h>
#pragma comment(lib, "WinInet.lib")
HINTERNET hInternet, hConnect = NULL;
// 建立会话
hInternet = InternetOpen(_T("WinInet Ftp"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0/*INTERNET_FLAG_ASYNC*/);
if (hInternet == nullptr)
return ;
// 建立连接
hConnect = InternetConnect(hInternet, m_strServer, m_nFtpPort/*INTERNET_INVALID_PORT_NUMBER*/, m_strUsername, m_strPassword,
INTERNET_SERVICE_FTP, INTERNET_FLAG_EXISTING_CONNECT || INTERNET_FLAG_PASSIVE, 0);
if (hConnect == nullptr)
{
InternetCloseHandle(hInternet);
return ;
}
// 获取远程文件大小信息
LARGE_INTEGER liSize = { 0 };
WIN32_FIND_DATA fileData;
std::string sRemoteFilename = "/远程文件名.xxx";
HINTERNET hRemoteFile = FtpFindFirstFile(hConnect, sRemoteFilename.c_str(), &fileData, 0, 0);
if (hRemoteFile == nullptr)
{
// 服务器不存在该文件
if (FtpGetFile(hConnect, sRemoteFilename.c_str(), "本地文件名.xxx", FTP_TRANSFER_TYPE_BINARY, 0))
{
// 文件下载成功
}
else
{
// 文件下载失败
}
return;
}
else
{
// 服务器存在该文件,启用断点续传
liSize.HighPart = fileData.nFileSizeHigh;
liSize.LowPart = fileData.nFileSizeLow;
InternetCloseHandle(hRemoteFile);
// 获取本地文件大小
DWORD dwSize = 0;
HANDLE hLocalFile = CreateFile("本地文件名.xxx", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ |
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
if (INVALID_HANDLE_VALUE == hLocalFile)
{
// 本地文件不存在
hLocalFile = CreateFile("本地文件名.xxx", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ |
FILE_SHARE_WRITE, NULL, ALWAYS_CREATE, FILE_ATTRIBUTE_ARCHIVE, NULL);
}
else
{
// 获取文件大小
dwSize = GetFileSize(hLocalFile, NULL);
}
BOOL bUploadOk = FALSE;
if (dwSize < liSize.QuadPart)
{
// 建立数据传输通道
HINTERNET hRemoteFile = nullptr;
std::string sCommand = format("REST %d", dwSize);
BOOL bRet = FtpCommand(hConnect, FALSE, FTP_TRANSFER_TYPE_BINARY, _T("REST 3\r\n"), 0, NULL);
sCommand = format("APPE %s", sRemoteFilename.c_str());
bRet = FtpCommand(hConnect, TRUE, FTP_TRANSFER_TYPE_BINARY, sCommand.c_str(), 0, &hRemoteFile);
if (bRet && hRemoteFile != nullptr)
{
// 本地文件大小比远程大,则续传
SetFilePointer(hLocalFile, dwSize, NULL, FILE_BEGIN);
while (TRUE)
{
char buffer[1024];
DWORD dwRet = 0;
if (InternetReadFile(hRemoteFile, buffer, 1024, &dwRet, NULL))
{
if (dwRet == 0)
{
// 文件读取完毕
break;
}
DWORD dwSize = 0;
if (!WriteFile(hLocalFile, buffer, dwRet, &dwSize))
{
// 写入失败
break;
}
}
else
{
break;
}
}
InternetCloseHandle(hRemoteFile);
}
else
{
// 远程文件访问失败
DWORD dwError;
TCHAR tpszBuff[2 * 1024];
DWORD dwBuffLen = 2 * 1024;
bRet = ::InternetGetLastResponseInfo(&dwError, tpszBuff, &dwBuffLen);
}
}
CloseHandle(hLocalFile);
}
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);