欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++實(shí)現(xiàn)FTP文件上傳下載的示例詳解

 更新時(shí)間:2023年12月01日 08:40:51   作者:微軟技術(shù)分享  
FTP(文件傳輸協(xié)議)是一種用于在網(wǎng)絡(luò)上傳輸文件的標(biāo)準(zhǔn)協(xié)議,這篇文章主要為大家詳細(xì)介紹了C++如何實(shí)現(xiàn)FTP文件上傳下載功能,需要的小伙伴可以參考下

FTP(文件傳輸協(xié)議)是一種用于在網(wǎng)絡(luò)上傳輸文件的標(biāo)準(zhǔn)協(xié)議。它屬于因特網(wǎng)標(biāo)準(zhǔn)化的協(xié)議族之一,為文件的上傳、下載和文件管理提供了一種標(biāo)準(zhǔn)化的方法,在Windows系統(tǒng)中操作FTP上傳下載可以使用WinINet庫,WinINet(Windows Internet)庫是 Windows 操作系統(tǒng)中的一個(gè)網(wǎng)絡(luò) API 庫,用于訪問 Internet 上的資源。它提供了一組函數(shù),使開發(fā)人員能夠創(chuàng)建網(wǎng)絡(luò)應(yīng)用程序,例如通過 HTTP 協(xié)議下載文件,發(fā)送 HTTP 請求,處理 cookie 等,本章將通過使用WinInet所提供的接口實(shí)現(xiàn)FTP文件上傳下載功能,使得用戶可以通過代碼的方式上傳或下載文件與FTP服務(wù)器交互。

首先讀者需要自行搭建FTP服務(wù)器,這里可以使用20CN Mini Ftp這款迷你FTP服務(wù)器,配置好信息之后運(yùn)行即可;

接著來介紹實(shí)現(xiàn)FTP通信的標(biāo)準(zhǔn)API函數(shù)信息,其核心的函數(shù)如下所示;

InternetOpen 函數(shù),用于初始化 WinINet 庫,返回一個(gè)句柄,該句柄可用于后續(xù)的網(wǎng)絡(luò)操作。以下是該函數(shù)的原型和簡要說明:

HINTERNET InternetOpen(
  LPCWSTR lpszAgent,  // 用戶代理字符串,標(biāo)識應(yīng)用程序的名稱
  DWORD   dwAccessType, // 訪問類型,可以是 DIRECT、PRECONFIG 或 PROXY
  LPCWSTR lpszProxyName, // 代理服務(wù)器名稱
  LPCWSTR lpszProxyBypass, // 代理服務(wù)器的繞過列表
  DWORD   dwFlags // 一些標(biāo)志,例如INTERNET_FLAG_ASYNC(異步操作)
);

lpszAgent: 用戶代理字符串,用于標(biāo)識應(yīng)用程序的名稱??梢允菓?yīng)用程序的名稱或標(biāo)識符。

dwAccessType: 訪問類型,指定應(yīng)用程序的訪問權(quán)限??梢允且韵轮抵唬?/p>

  • INTERNET_OPEN_TYPE_DIRECT: 直接訪問互聯(lián)網(wǎng)。
  • INTERNET_OPEN_TYPE_PRECONFIG: 使用系統(tǒng)配置的代理。
  • INTERNET_OPEN_TYPE_PROXY: 使用指定的代理。

lpszProxyName: 代理服務(wù)器的名稱,僅在 dwAccessType 為 INTERNET_OPEN_TYPE_PROXY 時(shí)使用。

lpszProxyBypass: 代理服務(wù)器的繞過列表,僅在 dwAccessType 為 INTERNET_OPEN_TYPE_PROXY 時(shí)使用。

dwFlags: 一些標(biāo)志,用于指定其他選項(xiàng),例如 INTERNET_FLAG_ASYNC 表示執(zhí)行異步操作。

該函數(shù)返回一個(gè) HINTERNET 句柄,用于后續(xù)的網(wǎng)絡(luò)操作。如果操作失敗,返回 NULL。在使用完 HINTERNET 句柄后,應(yīng)該使用 InternetCloseHandle 函數(shù)關(guān)閉該句柄。

InternetConnect 函數(shù),用于創(chuàng)建一個(gè)與指定服務(wù)器的連接。以下是該函數(shù)的原型和簡要說明:

HINTERNET InternetConnect(
  HINTERNET     hInternet,       // InternetOpen 返回的句柄
  LPCWSTR       lpszServerName,  // 服務(wù)器的主機(jī)名
  INTERNET_PORT nServerPort,      // 服務(wù)器的端口號
  LPCWSTR       lpszUsername,    // 用戶名
  LPCWSTR       lpszPassword,    // 密碼
  DWORD         dwService,       // 服務(wù)類型,例如 INTERNET_SERVICE_HTTP
  DWORD         dwFlags,         // 一些標(biāo)志,例如 INTERNET_FLAG_RELOAD
  DWORD_PTR     dwContext        // 應(yīng)用程序定義的上下文
);

hInternet: 由 InternetOpen 返回的句柄,表示與 WinINet 庫的連接。

lpszServerName: 服務(wù)器的主機(jī)名或 IP 地址。

nServerPort: 服務(wù)器的端口號。

lpszUsername: 連接需要的用戶名。

lpszPassword: 連接需要的密碼。

dwService: 服務(wù)類型,可以是以下值之一:

  • INTERNET_SERVICE_FTP: FTP 服務(wù)
  • INTERNET_SERVICE_HTTP: HTTP 服務(wù)
  • 其他服務(wù)類型,具體可查閱官方文檔。

dwFlags: 一些標(biāo)志,例如 INTERNET_FLAG_RELOAD 表示重新加載頁面。

dwContext: 應(yīng)用程序定義的上下文,可以是一個(gè)指針。

該函數(shù)返回一個(gè) HINTERNET 句柄,用于后續(xù)的網(wǎng)絡(luò)操作。如果操作失敗,返回 NULL。在使用完 HINTERNET 句柄后,應(yīng)該使用 InternetCloseHandle 函數(shù)關(guān)閉該句柄。

InternetWriteFile 函數(shù),用于向已打開的互聯(lián)網(wǎng)文件或句柄寫入數(shù)據(jù)。以下是該函數(shù)的原型和簡要說明:

BOOL InternetWriteFile(
  HINTERNET hFile,           // 由 InternetOpenUrl 或 HttpOpenRequest 返回的文件句柄
  LPCVOID   lpBuffer,        // 指向包含要寫入的數(shù)據(jù)的緩沖區(qū)的指針
  DWORD     dwNumberOfBytesToWrite,  // 要寫入的字節(jié)數(shù)
  LPDWORD   lpdwNumberOfBytesWritten  // 指向接收實(shí)際寫入的字節(jié)數(shù)的指針
);
  • hFile: 由 InternetOpenUrl 或 HttpOpenRequest 返回的文件句柄。
  • lpBuffer: 指向包含要寫入的數(shù)據(jù)的緩沖區(qū)的指針。
  • dwNumberOfBytesToWrite: 要寫入的字節(jié)數(shù)。
  • lpdwNumberOfBytesWritten: 指向接收實(shí)際寫入的字節(jié)數(shù)的指針。

該函數(shù)返回一個(gè)布爾值,指示操作是否成功。如果成功,返回 TRUE,否則返回 FALSE

InternetReadFile 函數(shù),用于從已打開的互聯(lián)網(wǎng)文件或句柄讀取數(shù)據(jù)。以下是該函數(shù)的原型和簡要說明:

BOOL InternetReadFile(
  HINTERNET hFile,         // 由 InternetOpenUrl 或 HttpOpenRequest 返回的文件句柄
  LPVOID    lpBuffer,      // 指向接收數(shù)據(jù)的緩沖區(qū)的指針
  DWORD     dwNumberOfBytesToRead,  // 要讀取的字節(jié)數(shù)
  LPDWORD   lpdwNumberOfBytesRead  // 指向接收實(shí)際讀取的字節(jié)數(shù)的指針
);
  • hFile: 由 InternetOpenUrl 或 HttpOpenRequest 返回的文件句柄。
  • lpBuffer: 指向接收數(shù)據(jù)的緩沖區(qū)的指針。
  • dwNumberOfBytesToRead: 要讀取的字節(jié)數(shù)。
  • lpdwNumberOfBytesRead: 指向接收實(shí)際讀取的字節(jié)數(shù)的指針。

該函數(shù)返回一個(gè)布爾值,指示操作是否成功。如果成功,返回 TRUE,否則返回 FALSE。

FTP文件下載

如下代碼是使用 WinInet 庫實(shí)現(xiàn)的 FTP 文件下載功能。以下是對該代碼的概述:

頭文件引入和庫鏈接

  • 代碼使用了 <Windows.h> 和 <WinInet.h> 頭文件,同時(shí)通過 #pragma comment(lib, "WinInet.lib") 鏈接了 WinInet 庫,這是使用 WinInet 庫的基本準(zhǔn)備工作。

FtpSaveToFile 函數(shù):

該函數(shù)用于將數(shù)據(jù)保存到本地文件。它通過調(diào)用 CreateFile 創(chuàng)建一個(gè)空文件,然后使用 WriteFile 將數(shù)據(jù)寫入文件,最后關(guān)閉文件句柄。這個(gè)函數(shù)在 FTP 文件下載后保存文件到本地。

FTPDownload 函數(shù)

  • 這是主要的 FTP 下載函數(shù)。它使用 WinInet 提供的函數(shù)建立了一個(gè) FTP 會話,連接到指定的 FTP 服務(wù)器,打開指定路徑的文件,并通過循環(huán)調(diào)用 InternetReadFile 讀取文件內(nèi)容。
  • 下載的數(shù)據(jù)以字節(jié)數(shù)組的形式保存在 pDownloadData 中,下載完成后,調(diào)用 FtpSaveToFile 函數(shù)將數(shù)據(jù)保存到本地文件。

注意事項(xiàng)

  • 代碼中使用了 RtlZeroMemory 函數(shù)清空內(nèi)存,確保數(shù)據(jù)緩沖區(qū)的正確初始化。
  • 注意釋放動態(tài)分配的內(nèi)存,避免內(nèi)存泄漏。

函數(shù)參數(shù)

函數(shù)參數(shù)包括 FTP 服務(wù)器的主機(jī)名 (szHostName)、用戶名 (szUserName)、密碼 (szPassword)、FTP 路徑 (szUrlPath),以及本地保存路徑 (SavePath)。

總體而言,這段代碼實(shí)現(xiàn)了基本的 FTP 文件下載功能,適用于從 FTP 服務(wù)器下載文件到本地。在使用時(shí),確保提供正確的 FTP 服務(wù)器信息和路徑,以及合適的本地保存路徑。

#include <iostream>
#include <Windows.h>
#include <WinInet.h>

#pragma comment(lib, "WinInet.lib")

// 保存文件到本地
BOOL FtpSaveToFile(char *pszFileName, BYTE *pData, DWORD dwDataSize)
{
	// 創(chuàng)建空文件
	HANDLE hFile = CreateFile(pszFileName, GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
		FILE_ATTRIBUTE_ARCHIVE, NULL);
	if (INVALID_HANDLE_VALUE == hFile)
		return FALSE;

	DWORD dwRet = 0;

	// 寫出數(shù)據(jù)到文件
	WriteFile(hFile, pData, dwDataSize, &dwRet, NULL);

	// 關(guān)閉句柄
	CloseHandle(hFile);
	return TRUE;
}

BOOL FTPDownload(char *szHostName, char *szUserName, char *szPassword, char *szUrlPath, char *SavePath)
{
	HINTERNET hInternet, hConnect, hFTPFile = NULL;
	BYTE *pDownloadData = NULL;
	DWORD dwDownloadDataSize = 0;
	DWORD dwBufferSize = 4096;
	BYTE *pBuf = NULL;
	DWORD dwBytesReturn = 0;
	DWORD dwOffset = 0;
	BOOL bRet = FALSE;

	// 建立會話并打開FTP操作
	hInternet = InternetOpen("WinInet Ftp", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	hConnect = InternetConnect(hInternet, szHostName, INTERNET_INVALID_PORT_NUMBER,szUserName, szPassword, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
	hFTPFile = FtpOpenFile(hConnect, szUrlPath, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_RELOAD, NULL);
	
	// 獲取文件大小并初始化緩沖區(qū)
	dwDownloadDataSize = FtpGetFileSize(hFTPFile, NULL);
	pDownloadData = new BYTE[dwDownloadDataSize];
	RtlZeroMemory(pDownloadData, dwDownloadDataSize);
	pBuf = new BYTE[dwBufferSize];
	RtlZeroMemory(pBuf, dwBufferSize);
	
	// 循環(huán)接收數(shù)據(jù)
	do
	{
		// 讀取數(shù)據(jù)
		bRet = InternetReadFile(hFTPFile, pBuf, dwBufferSize, &dwBytesReturn);
		if (FALSE == bRet)
			break;
		
		// 將讀取到的數(shù)據(jù)追加到內(nèi)存
		RtlCopyMemory((pDownloadData + dwOffset), pBuf, dwBytesReturn);
		dwOffset = dwOffset + dwBytesReturn;
	} while (dwDownloadDataSize > dwOffset);

	// 保存變量中的數(shù)據(jù)為文件
	FtpSaveToFile(SavePath, pDownloadData, dwDownloadDataSize);
	
	// 釋放內(nèi)存
	delete[]pDownloadData;
	pDownloadData = NULL;
	return TRUE;
}

調(diào)用FTPDownload時(shí)分別傳入?yún)?shù),參數(shù)1是IP地址,參數(shù)2是FTP登錄用戶名,參數(shù)3是FTP登錄密碼,參數(shù)4是服務(wù)器端根目錄下的文件,參數(shù)5是下載文件到本地的路徑,函數(shù)執(zhí)行結(jié)束后返回一個(gè)BOOL狀態(tài)值。

int main(int argc, char * argv[])
{
	BOOL bRET = FTPDownload("127.0.0.1", "admin", "admin", "/lyshark.jpg", "d://newtest/lyshark.jpg");
	if (bRET == TRUE)
	{
		printf("已下載文件 \n");
	}
	else
	{
		printf("下載失敗 \n");
	}

	system("pause");
	return 0;
}

運(yùn)行后則可以將服務(wù)器端上的/lyshark.jpg下載到本地的d://newtest/lyshark.jpg目錄下,如下圖所示;

FTP文件上傳

如下代碼使用 WinInet 庫實(shí)現(xiàn)了 FTP 文件上傳操作。以下是對該代碼的概述:

函數(shù)功能

該代碼實(shí)現(xiàn)了 FTP 文件上傳操作,將本地文件上傳到指定的 FTP 服務(wù)器路徑。

函數(shù)參數(shù)

函數(shù)參數(shù)包括 FTP 服務(wù)器的主機(jī)名 (szHostName)、用戶名 (szUserName)、密碼 (szPassword)、FTP 路徑 (szUrlPath),以及本地文件路徑 (FilePath)。

建立會話和連接

使用 InternetOpen 函數(shù)建立一個(gè) WinInet 會話,然后使用 InternetConnect 函數(shù)建立到 FTP 服務(wù)器的連接。

打開 FTP 文件

使用 FtpOpenFile 函數(shù)打開指定路徑的 FTP 文件。如果文件不存在,將創(chuàng)建一個(gè)新文件。文件以二進(jìn)制傳輸方式打開,并且具有重新加載標(biāo)志。

打開本地文件

使用 CreateFile 函數(shù)打開本地文件。如果本地文件不存在,將返回 INVALID_HANDLE_VALUE。

獲取文件大小和讀取文件數(shù)據(jù)

通過 GetFileSize 獲取本地文件大小,然后根據(jù)文件大小動態(tài)分配內(nèi)存,并使用 ReadFile 讀取文件數(shù)據(jù)到內(nèi)存中。

上傳數(shù)據(jù)

使用 InternetWriteFile 函數(shù)將內(nèi)存中的文件數(shù)據(jù)上傳到 FTP 服務(wù)器。上傳成功后釋放內(nèi)存,上傳失敗則返回 FALSE。

注意事項(xiàng)

  • 確保提供正確的 FTP 服務(wù)器信息和路徑,以及本地文件路徑。
  • 釋放動態(tài)分配的內(nèi)存,避免內(nèi)存泄漏。
  • 處理上傳失敗的情況,可能需要添加適當(dāng)?shù)腻e(cuò)誤處理代碼。

總體而言,這段代碼實(shí)現(xiàn)了基本的 FTP 文件上傳功能,適用于將本地文件上傳到 FTP 服務(wù)器。在使用時(shí),注意提供正確的參數(shù)和處理可能出現(xiàn)的錯(cuò)誤。

#include <iostream>
#include <Windows.h>
#include <WinInet.h>

#pragma comment(lib, "WinInet.lib")

// 實(shí)現(xiàn)文件上傳操作
BOOL FTPUpload(char *szHostName, char *szUserName, char *szPassword, char *szUrlPath, char *FilePath)
{
  HINTERNET hInternet, hConnect, hFTPFile = NULL;
  DWORD dwBytesReturn = 0;
  DWORD UploadDataSize = 0;
  BYTE *pUploadData = NULL;
  DWORD dwRet, bRet = 0;

  // 建立會話并打開FTP操作
  hInternet = InternetOpen("WinInet Ftp", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
  hConnect = InternetConnect(hInternet, szHostName, INTERNET_INVALID_PORT_NUMBER, szUserName, szPassword, 
    INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
  hFTPFile = FtpOpenFile(hConnect, szUrlPath, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_RELOAD, NULL);

  // 打開文件
  HANDLE hFile = CreateFile(FilePath, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | 
    FILE_SHARE_WRITE, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE, NULL);
  if (INVALID_HANDLE_VALUE == hFile)
    return FALSE;

  // 獲取文件大小
  UploadDataSize = GetFileSize(hFile, NULL);
  pUploadData = new BYTE[UploadDataSize];
  // 讀取文件到緩沖區(qū)
  ReadFile(hFile, pUploadData, UploadDataSize, &dwRet, NULL);
  UploadDataSize = dwRet;

  // 開始上傳數(shù)據(jù)
  bRet = InternetWriteFile(hFTPFile, pUploadData, UploadDataSize, &dwBytesReturn);
  if (FALSE == bRet)
  {
    delete[]pUploadData;
    return FALSE;
  }
  delete[]pUploadData;
  return TRUE;
}

文件上傳與下載一樣,FTPUpload通過傳入服務(wù)器地址,用戶名,密碼,上傳后的文件名,被上傳本地文件路徑;

int main(int argc, char * argv[])
{
	BOOL bRET = FTPUpload("127.0.0.1", "admin", "admin", "/abc.exe", "c://nc.exe");
	if (bRET == TRUE)
	{
		printf("已上傳文件 \n");
	}
	else
	{
		printf("上傳失敗 \n");
	}

	system("pause");
	return 0;
}

上傳成功后輸出如下圖所示;

以上就是C/C++實(shí)現(xiàn)FTP文件上傳下載的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于C++ FTP文件上傳下載的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • VC實(shí)現(xiàn)ODBC數(shù)據(jù)庫操作實(shí)例解析

    VC實(shí)現(xiàn)ODBC數(shù)據(jù)庫操作實(shí)例解析

    這篇文章主要介紹了VC實(shí)現(xiàn)ODBC數(shù)據(jù)庫操作的方法,非常有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-07-07
  • C++使用jsoncpp庫解析Json

    C++使用jsoncpp庫解析Json

    對json的解析操作是我們?nèi)粘i_發(fā)中經(jīng)常會遇到的一個(gè)需求,下面這篇文章主要給大家介紹了關(guān)于C++使用jsoncpp庫解析Json的相關(guān)資料,需要的朋友可以參考下
    2021-06-06
  • 單線程會導(dǎo)致死鎖你知道嗎

    單線程會導(dǎo)致死鎖你知道嗎

    這篇文章主要為大家詳細(xì)介紹了單線程會不會導(dǎo)致死鎖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • VC實(shí)現(xiàn)批量刪除指定文件的方法

    VC實(shí)現(xiàn)批量刪除指定文件的方法

    這篇文章主要介紹了VC實(shí)現(xiàn)批量刪除指定文件的方法,是一個(gè)比較普遍且實(shí)用的功能,需要的朋友可以參考下
    2014-07-07
  • C++中指針的詳解及其作用介紹

    C++中指針的詳解及其作用介紹

    這篇文章主要介紹了C++中指針的詳解及其作用介紹,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • C++?OpenCV實(shí)現(xiàn)白平衡之完美反射算法

    C++?OpenCV實(shí)現(xiàn)白平衡之完美反射算法

    完美反射算法是白平衡各種算法中較常見的一種,比灰度世界算法更優(yōu)。本文將利用C++和OpenCV實(shí)現(xiàn)白平衡中的完美反射算法,需要的可以參考一下
    2022-05-05
  • C語言之system函數(shù)案例詳解

    C語言之system函數(shù)案例詳解

    這篇文章主要介紹了C語言之system函數(shù)案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • QT進(jìn)行CSV文件初始化與讀寫操作

    QT進(jìn)行CSV文件初始化與讀寫操作

    這篇文章主要為大家詳細(xì)介紹了在QT環(huán)境中如何進(jìn)行CSV文件的初始化、寫入和讀取操作,本文為大家整理了相關(guān)的操作的多種方法,希望對大家有所幫助
    2025-04-04
  • C 語言基礎(chǔ)教程(我的C之旅開始了)[三]

    C 語言基礎(chǔ)教程(我的C之旅開始了)[三]

    C 語言基礎(chǔ)教程(我的C之旅開始了)[三]...
    2007-02-02
  • C++ 實(shí)現(xiàn)L2-002 鏈表去重

    C++ 實(shí)現(xiàn)L2-002 鏈表去重

    這篇文章主要介紹了C++ 實(shí)現(xiàn)L2-002 鏈表去重,本文通過簡要的案例,解題思路講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07

最新評論