VC++ FTP文件下传(断点续传)

#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);

猜你喜欢

转载自blog.csdn.net/u012156872/article/details/118335391