国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C/C++ 通過(guò)HTTP實(shí)現(xiàn)文件上傳下載

這篇具有很好參考價(jià)值的文章主要介紹了C/C++ 通過(guò)HTTP實(shí)現(xiàn)文件上傳下載。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

WinInet(Windows Internet)是 Microsoft Windows 操作系統(tǒng)中的一個(gè) API 集,用于提供對(duì) Internet 相關(guān)功能的支持。它包括了一系列的函數(shù),使得 Windows 應(yīng)用程序能夠進(jìn)行網(wǎng)絡(luò)通信、處理 HTTP 請(qǐng)求、FTP 操作等。WinInet 提供了一套完整的網(wǎng)絡(luò)通信工具,使得開發(fā)者能夠輕松地構(gòu)建支持網(wǎng)絡(luò)功能的應(yīng)用程序,涵蓋了從簡(jiǎn)單的 HTTP 請(qǐng)求到復(fù)雜的文件傳輸?shù)榷喾N網(wǎng)絡(luò)操作。

分解URL地址

InternetCrackUrl 函數(shù)可實(shí)現(xiàn)對(duì)URL字符串進(jìn)行解析,提取其中的協(xié)議、主機(jī)名、端口、路徑和其他信息,并將這些信息存儲(chǔ)在 URL_COMPONENTS 結(jié)構(gòu)中,方便后續(xù)的網(wǎng)絡(luò)操作,該函數(shù)是Windows下默認(rèn)提供的,函數(shù)與依賴結(jié)果如下所示;

函數(shù)原型

BOOL InternetCrackUrl(
  LPCTSTR      lpszUrl,
  DWORD        dwUrlLength,
  DWORD        dwFlags,
  LPURL_COMPONENTS lpUrlComponents
);

參數(shù)說(shuō)明

  • lpszUrl:指定待解析的 URL 字符串。
  • dwUrlLength:指定 URL 字符串的長(zhǎng)度。
  • dwFlags:指定解析 URL 的標(biāo)志,可以是以下值之一:
    • ICU_DECODE:對(duì) URL 進(jìn)行解碼。
    • ICU_ESCAPE:對(duì) URL 進(jìn)行轉(zhuǎn)義。
  • lpUrlComponents:一個(gè)指向 URL_COMPONENTS 結(jié)構(gòu)的指針,用于存儲(chǔ)解析后的各個(gè)部分信息。

URL_COMPONENTS結(jié)構(gòu)

typedef struct {
  DWORD dwStructSize;
  LPTSTR lpszScheme;
  DWORD dwSchemeLength;
  INTERNET_SCHEME nScheme;
  LPTSTR lpszHostName;
  DWORD dwHostNameLength;
  INTERNET_PORT nPort;
  LPTSTR lpszUserName;
  DWORD dwUserNameLength;
  LPTSTR lpszPassword;
  DWORD dwPasswordLength;
  LPTSTR lpszUrlPath;
  DWORD dwUrlPathLength;
  LPTSTR lpszExtraInfo;
  DWORD dwExtraInfoLength;
} URL_COMPONENTS, *LPURL_COMPONENTS;

返回值

如果函數(shù)成功,返回 TRUE,并在 lpUrlComponents 結(jié)構(gòu)中存儲(chǔ)解析后的信息;如果失敗,返回 FALSE。在失敗時(shí),可以調(diào)用 GetLastError 函數(shù)獲取詳細(xì)的錯(cuò)誤信息。

函數(shù)調(diào)用

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

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

using namespace std;

BOOL UrlCrack(char* pszUrl, char* pszScheme, char* pszHostName, char* pszUserName, char* pszPassword, char* pszUrlPath, char* pszExtraInfo, DWORD dwBufferSize)
{
	BOOL bRet = FALSE;
	URL_COMPONENTS uc = { 0 };

	// 初始化變量中的內(nèi)容
	RtlZeroMemory(&uc, sizeof(uc));
	RtlZeroMemory(pszScheme, dwBufferSize);
	RtlZeroMemory(pszHostName, dwBufferSize);
	RtlZeroMemory(pszUserName, dwBufferSize);
	RtlZeroMemory(pszPassword, dwBufferSize);
	RtlZeroMemory(pszUrlPath, dwBufferSize);
	RtlZeroMemory(pszExtraInfo, dwBufferSize);

	// 將長(zhǎng)度填充到結(jié)構(gòu)中
	uc.dwStructSize = sizeof(uc);
	uc.dwSchemeLength = dwBufferSize - 1;
	uc.dwHostNameLength = dwBufferSize - 1;
	uc.dwUserNameLength = dwBufferSize - 1;
	uc.dwPasswordLength = dwBufferSize - 1;
	uc.dwUrlPathLength = dwBufferSize - 1;
	uc.dwExtraInfoLength = dwBufferSize - 1;
	uc.lpszScheme = pszScheme;
	uc.lpszHostName = pszHostName;
	uc.lpszUserName = pszUserName;
	uc.lpszPassword = pszPassword;
	uc.lpszUrlPath = pszUrlPath;
	uc.lpszExtraInfo = pszExtraInfo;

	// 分解URL地址
	bRet = InternetCrackUrl(pszUrl, 0, 0, &uc);
	if (FALSE == bRet)
	{
		return bRet;
	}
	return bRet;
}

int main(int argc, char* argv[])
{
	char szHttpDownloadUrl[] = "http://www.lyshark.com/index.php&username=lyshark&password=123";

	// 對(duì)應(yīng)的變量
	char szScheme[MAX_PATH] = { 0 };
	char szHostName[MAX_PATH] = { 0 };
	char szUserName[MAX_PATH] = { 0 };
	char szPassword[MAX_PATH] = { 0 };
	char szUrlPath[MAX_PATH] = { 0 };
	char szExtraInfo[MAX_PATH] = { 0 };

	// 初始化用0填充
	RtlZeroMemory(szScheme, MAX_PATH);
	RtlZeroMemory(szHostName, MAX_PATH);
	RtlZeroMemory(szUserName, MAX_PATH);
	RtlZeroMemory(szPassword, MAX_PATH);
	RtlZeroMemory(szUrlPath, MAX_PATH);
	RtlZeroMemory(szExtraInfo, MAX_PATH);

	// 分解URL
	if (FALSE == UrlCrack(szHttpDownloadUrl, szScheme, szHostName, szUserName, szPassword, szUrlPath, szExtraInfo, MAX_PATH))
	{
		return FALSE;
	}

	std::cout << szScheme << std::endl;
	std::cout << szHostName << std::endl;
	std::cout << szUserName << std::endl;
	std::cout << szPassword << std::endl;
	std::cout << szUrlPath << std::endl;
	std::cout << szExtraInfo << std::endl;

	system("pause");
	return 0;
}

運(yùn)行代碼輸出特定網(wǎng)址的每個(gè)部分,如下圖所示;

c++下載文件,《Visual C++ 編程技術(shù)實(shí)踐》,c語(yǔ)言,c++,http,文件上傳下載

下載頁(yè)面內(nèi)容

InternetOpen

用于初始化 WinINet 函數(shù)的使用。以下是該函數(shù)的原型:

HINTERNET InternetOpen(
  LPCWSTR lpszAgent,
  DWORD   dwAccessType,
  LPCWSTR lpszProxyName,
  LPCWSTR lpszProxyBypass,
  DWORD   dwFlags
);

參數(shù)說(shuō)明:

  • lpszAgent: 指定應(yīng)用程序的名稱,用于標(biāo)識(shí)調(diào)用 InternetOpen 的應(yīng)用程序。
  • dwAccessType: 指定訪問(wèn)類型,可以是 INTERNET_OPEN_TYPE_DIRECTINTERNET_OPEN_TYPE_PROXYINTERNET_OPEN_TYPE_PRECONFIG 中的一個(gè)。
  • lpszProxyName: 如果 dwAccessTypeINTERNET_OPEN_TYPE_PROXY,則指定代理服務(wù)器的名稱。否則,可以設(shè)為 NULL。
  • lpszProxyBypass: 如果 dwAccessTypeINTERNET_OPEN_TYPE_PROXY,則指定繞過(guò)代理服務(wù)器的地址。否則,可以設(shè)為 NULL。
  • dwFlags: 一些標(biāo)志,可以用來(lái)指定額外的行為,如 INTERNET_FLAG_ASYNC 用于異步操作。

返回值:

如果函數(shù)調(diào)用成功,將返回一個(gè)類型為 HINTERNET 的句柄,用于后續(xù)的 WinINet 操作。如果函數(shù)調(diào)用失敗,返回 NULL??梢允褂?GetLastError 函數(shù)獲取詳細(xì)的錯(cuò)誤信息。

InternetConnect

用于建立到遠(yuǎn)程服務(wù)器的連接。以下是該函數(shù)的原型:

HINTERNET InternetConnect(
  HINTERNET     hInternet,
  LPCWSTR       lpszServerName,
  INTERNET_PORT nServerPort,
  LPCWSTR       lpszUserName,
  LPCWSTR       lpszPassword,
  DWORD         dwService,
  DWORD         dwFlags,
  DWORD_PTR     dwContext
);

參數(shù)說(shuō)明:

  • hInternet: 調(diào)用 InternetOpen 返回的句柄,表示連接的上下文。
  • lpszServerName: 要連接的服務(wù)器的名稱或 IP 地址。
  • nServerPort: 服務(wù)器的端口號(hào)。
  • lpszUserName: 連接服務(wù)器時(shí)要使用的用戶名,可以為 NULL
  • lpszPassword: 連接服務(wù)器時(shí)要使用的密碼,可以為 NULL
  • dwService: 指定服務(wù)類型,可以是 INTERNET_SERVICE_FTP、INTERNET_SERVICE_HTTP 或其他服務(wù)類型。
  • dwFlags: 一些標(biāo)志,用于指定連接的屬性,如 INTERNET_FLAG_RELOAD、INTERNET_FLAG_SECURE 等。
  • dwContext: 用戶定義的應(yīng)用程序上下文,將在回調(diào)函數(shù)中使用。

返回值:

如果函數(shù)調(diào)用成功,將返回一個(gè)類型為 HINTERNET 的句柄,表示連接的上下文。如果函數(shù)調(diào)用失敗,返回 NULL??梢允褂?GetLastError 函數(shù)獲取詳細(xì)的錯(cuò)誤信息。

InternetConnect 用于建立連接后,可以使用返回的句柄執(zhí)行相關(guān)的協(xié)議操作,如 FTP 或 HTTP 操作。使用完連接后,同樣需要使用 InternetCloseHandle 函數(shù)關(guān)閉相應(yīng)的句柄,以釋放資源。

HttpOpenRequest

它是在使用 WinINet 庫(kù)進(jìn)行 HTTP 操作時(shí)的一部分。以下是該函數(shù)的原型:

HINTERNET HttpOpenRequest(
  HINTERNET hConnect,
  LPCWSTR   lpszVerb,
  LPCWSTR   lpszObjectName,
  LPCWSTR   lpszVersion,
  LPCWSTR   lpszReferrer,
  LPCWSTR   *lplpszAcceptTypes,
  DWORD     dwFlags,
  DWORD_PTR dwContext
);

參數(shù)說(shuō)明:

  • hConnect: 調(diào)用 InternetConnect 返回的連接句柄,表示請(qǐng)求的上下文。
  • lpszVerb: HTTP 請(qǐng)求方法,如 “GET”、“POST” 等。
  • lpszObjectName: 請(qǐng)求的對(duì)象名,通常是 URL 的路徑部分。
  • lpszVersion: HTTP 協(xié)議版本,通常是 “HTTP/1.1”。
  • lpszReferrer: 引用的來(lái)源,可以為 NULL。
  • lplpszAcceptTypes: 指定可接受的媒體類型,可以為 NULL。
  • dwFlags: 一些標(biāo)志,用于指定請(qǐng)求的屬性,如 INTERNET_FLAG_RELOAD、INTERNET_FLAG_SECURE 等。
  • dwContext: 用戶定義的應(yīng)用程序上下文,將在回調(diào)函數(shù)中使用。

返回值:

如果函數(shù)調(diào)用成功,將返回一個(gè)類型為 HINTERNET 的句柄,表示打開的 HTTP 請(qǐng)求。如果函數(shù)調(diào)用失敗,返回 NULL。可以使用 GetLastError 函數(shù)獲取詳細(xì)的錯(cuò)誤信息。

一旦打開了 HTTP 請(qǐng)求,可以使用返回的句柄執(zhí)行發(fā)送請(qǐng)求、接收響應(yīng)等操作。使用完請(qǐng)求后,同樣需要使用 InternetCloseHandle 函數(shù)關(guān)閉相應(yīng)的句柄,以釋放資源。

HttpSendRequest

用于發(fā)送 HTTP 請(qǐng)求的函數(shù),通常在使用 WinINet 庫(kù)進(jìn)行 HTTP 操作時(shí)調(diào)用。以下是該函數(shù)的原型:

BOOL HttpSendRequest(
  HINTERNET hRequest,
  LPCWSTR   lpszHeaders,
  DWORD     dwHeadersLength,
  LPVOID    lpOptional,
  DWORD     dwOptionalLength
);

參數(shù)說(shuō)明:

  • hRequest: 調(diào)用 HttpOpenRequest 返回的 HTTP 請(qǐng)求句柄,表示要發(fā)送請(qǐng)求的上下文。
  • lpszHeaders: 包含請(qǐng)求頭信息的字符串,可以為 NULL。
  • dwHeadersLength: 請(qǐng)求頭的長(zhǎng)度,如果 lpszHeadersNULL,則可以為零。
  • lpOptional: 包含請(qǐng)求的可選數(shù)據(jù)的緩沖區(qū),可以為 NULL。
  • dwOptionalLength: 可選數(shù)據(jù)的長(zhǎng)度,如果 lpOptionalNULL,則可以為零。

返回值:

如果函數(shù)調(diào)用成功,返回非零值;如果函數(shù)調(diào)用失敗,返回零??梢允褂?GetLastError 函數(shù)獲取詳細(xì)的錯(cuò)誤信息。

HttpSendRequest 用于實(shí)際發(fā)送 HTTP 請(qǐng)求。在調(diào)用此函數(shù)之后,可以使用其他 WinINet 函數(shù)來(lái)讀取服務(wù)器的響應(yīng)。同樣,使用完請(qǐng)求后,需要使用 InternetCloseHandle 函數(shù)關(guān)閉相應(yīng)的句柄,以釋放資源。

HttpQueryInfo

用于檢索有關(guān) HTTP 請(qǐng)求或響應(yīng)的信息的函數(shù),通常在使用 WinINet 庫(kù)進(jìn)行 HTTP 操作時(shí)調(diào)用。以下是該函數(shù)的原型:

BOOL HttpQueryInfo(
  HINTERNET hRequest,
  DWORD     dwInfoLevel,
  LPVOID    lpBuffer,
  LPDWORD   lpdwBufferLength,
  LPDWORD   lpdwIndex
);

參數(shù)說(shuō)明:

  • hRequest: 調(diào)用 HttpOpenRequest 返回的 HTTP 請(qǐng)求句柄,表示要查詢信息的上下文。
  • dwInfoLevel: 指定要檢索的信息類型,可以是預(yù)定義的常量,如 HTTP_QUERY_STATUS_CODE、HTTP_QUERY_CONTENT_TYPE 等。
  • lpBuffer: 用于接收檢索到的信息的緩沖區(qū)。
  • lpdwBufferLength: 指向一個(gè)變量,表示 lpBuffer 緩沖區(qū)的大小。在調(diào)用函數(shù)前,應(yīng)該將該變量設(shè)置為 lpBuffer 緩沖區(qū)的大小。在調(diào)用函數(shù)后,該變量將包含實(shí)際寫入緩沖區(qū)的字節(jié)數(shù)。
  • lpdwIndex: 如果請(qǐng)求返回多個(gè)值,可以使用此參數(shù)指定要檢索的值的索引。對(duì)于單值的信息,可以將其設(shè)置為 NULL。

返回值:

如果函數(shù)調(diào)用成功,返回非零值;如果函數(shù)調(diào)用失敗,返回零。可以使用 GetLastError 函數(shù)獲取詳細(xì)的錯(cuò)誤信息。

HttpQueryInfo 用于獲取與 HTTP 請(qǐng)求或響應(yīng)相關(guān)的信息,如狀態(tài)碼、內(nèi)容類型等。注意,在調(diào)用此函數(shù)之前,通常需要先調(diào)用 HttpSendRequest 發(fā)送請(qǐng)求。同樣,使用完請(qǐng)求后,需要使用 InternetCloseHandle 函數(shù)關(guān)閉相應(yīng)的句柄,以釋放資源。

InternetReadFile

用于從指定的句柄讀取數(shù)據(jù)的函數(shù),通常在使用 WinINet 庫(kù)進(jìn)行網(wǎng)絡(luò)操作時(shí)調(diào)用。以下是該函數(shù)的原型:

BOOL InternetReadFile(
  HINTERNET hFile,
  LPVOID    lpBuffer,
  DWORD     dwNumberOfBytesToRead,
  LPDWORD   lpdwNumberOfBytesRead
);

參數(shù)說(shuō)明:

  • hFile: 調(diào)用 HttpOpenRequestFtpOpenFile 返回的句柄,表示要讀取數(shù)據(jù)的上下文。
  • lpBuffer: 用于接收讀取到的數(shù)據(jù)的緩沖區(qū)。
  • dwNumberOfBytesToRead: 指定要讀取的字節(jié)數(shù)。
  • lpdwNumberOfBytesRead: 指向一個(gè)變量,表示 lpBuffer 緩沖區(qū)中實(shí)際讀取的字節(jié)數(shù)。在調(diào)用函數(shù)前,應(yīng)該將該變量設(shè)置為 lpBuffer 緩沖區(qū)的大小。在調(diào)用函數(shù)后,該變量將包含實(shí)際讀取的字節(jié)數(shù)。

返回值:

如果函數(shù)調(diào)用成功,返回非零值;如果函數(shù)調(diào)用失敗,返回零??梢允褂?GetLastError 函數(shù)獲取詳細(xì)的錯(cuò)誤信息。

InternetReadFile 用于從網(wǎng)絡(luò)資源中讀取數(shù)據(jù),如從 HTTP 請(qǐng)求的響應(yīng)中讀取內(nèi)容。在調(diào)用此函數(shù)之前,通常需要先調(diào)用其他相關(guān)的函數(shù),如 HttpOpenRequest、HttpSendRequestHttpQueryInfo。同樣,使用完資源后,需要使用 InternetCloseHandle 函數(shù)關(guān)閉相應(yīng)的句柄,以釋放資源。

下載頁(yè)面的完整代碼是這樣的,如下所示;

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

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

using namespace std;

BOOL UrlCrack(char* pszUrl, char* pszScheme, char* pszHostName, char* pszUserName, char* pszPassword, char* pszUrlPath, char* pszExtraInfo, DWORD dwBufferSize)
{
	BOOL bRet = FALSE;
	URL_COMPONENTS uc = { 0 };

	// 初始化變量中的內(nèi)容
	RtlZeroMemory(&uc, sizeof(uc));
	RtlZeroMemory(pszScheme, dwBufferSize);
	RtlZeroMemory(pszHostName, dwBufferSize);
	RtlZeroMemory(pszUserName, dwBufferSize);
	RtlZeroMemory(pszPassword, dwBufferSize);
	RtlZeroMemory(pszUrlPath, dwBufferSize);
	RtlZeroMemory(pszExtraInfo, dwBufferSize);

	// 將長(zhǎng)度填充到結(jié)構(gòu)中
	uc.dwStructSize = sizeof(uc);
	uc.dwSchemeLength = dwBufferSize - 1;
	uc.dwHostNameLength = dwBufferSize - 1;
	uc.dwUserNameLength = dwBufferSize - 1;
	uc.dwPasswordLength = dwBufferSize - 1;
	uc.dwUrlPathLength = dwBufferSize - 1;
	uc.dwExtraInfoLength = dwBufferSize - 1;
	uc.lpszScheme = pszScheme;
	uc.lpszHostName = pszHostName;
	uc.lpszUserName = pszUserName;
	uc.lpszPassword = pszPassword;
	uc.lpszUrlPath = pszUrlPath;
	uc.lpszExtraInfo = pszExtraInfo;

	// 分解URL地址
	bRet = InternetCrackUrl(pszUrl, 0, 0, &uc);
	if (FALSE == bRet)
	{
		return bRet;
	}
	return bRet;
}

// 從響應(yīng)信息頭信息中獲取數(shù)據(jù)內(nèi)容長(zhǎng)度大小
BOOL GetContentLength(char* pResponseHeader, DWORD* pdwContentLength)
{
	int i = 0;
	char szContentLength[MAX_PATH] = { 0 };
	DWORD dwContentLength = 0;
	char szSubStr[] = "Content-Length: ";
	RtlZeroMemory(szContentLength, MAX_PATH);

	// 在傳入字符串中查找子串
	char* p = strstr(pResponseHeader, szSubStr);
	if (NULL == p)
	{
		return FALSE;
	}

	p = p + lstrlen(szSubStr);
	
	// 如果找到了就提取出里面的純數(shù)字
	while (('0' <= *p) && ('9' >= *p))
	{
		szContentLength[i] = *p;
		p++;
		i++;
	}

	// 字符串轉(zhuǎn)數(shù)字
	dwContentLength = atoi(szContentLength);
	*pdwContentLength = dwContentLength;
	return TRUE;
}

// 數(shù)據(jù)下載
BOOL HttpDownload(char* pszDownloadUrl, BYTE** ppDownloadData, DWORD* pdwDownloadDataSize)
{
	// 定義HTTP子變量
	char szScheme[MAX_PATH] = { 0 };
	char szHostName[MAX_PATH] = { 0 };
	char szUserName[MAX_PATH] = { 0 };
	char szPassword[MAX_PATH] = { 0 };
	char szUrlPath[MAX_PATH] = { 0 };
	char szExtraInfo[MAX_PATH] = { 0 };

	// 填充為空
	RtlZeroMemory(szScheme, MAX_PATH);
	RtlZeroMemory(szHostName, MAX_PATH);
	RtlZeroMemory(szUserName, MAX_PATH);
	RtlZeroMemory(szPassword, MAX_PATH);
	RtlZeroMemory(szUrlPath, MAX_PATH);
	RtlZeroMemory(szExtraInfo, MAX_PATH);

	// 拆解URL地址
	if (FALSE == UrlCrack(pszDownloadUrl, szScheme, szHostName, szUserName, szPassword, szUrlPath, szExtraInfo, MAX_PATH))
	{
		return FALSE;
	}

	// 數(shù)據(jù)下載
	HINTERNET hInternet = NULL;
	HINTERNET hConnect = NULL;
	HINTERNET hRequest = NULL;
	DWORD dwOpenRequestFlags = 0;
	BOOL bRet = FALSE;
	unsigned char* pResponseHeaderIInfo = NULL;
	DWORD dwResponseHeaderIInfoSize = 2048;
	BYTE* pBuf = NULL;
	DWORD dwBufSize = 64 * 1024;
	BYTE* pDownloadData = NULL;
	DWORD dwDownloadDataSize = 0;
	DWORD dwRet = 0;
	DWORD dwOffset = 0;

	do
	{
		// 建立會(huì)話
		hInternet = InternetOpen("WinInetGet/0.1", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
		if (NULL == hInternet)
		{
			break;
		}

		// 建立連接
		hConnect = InternetConnect(hInternet, szHostName, INTERNET_DEFAULT_HTTP_PORT, szUserName, szPassword, INTERNET_SERVICE_HTTP, 0, 0);
		if (NULL == hConnect)
		{
			break;
		}

		// 打開并發(fā)送HTTP請(qǐng)求
		dwOpenRequestFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
			INTERNET_FLAG_KEEP_CONNECTION |
			INTERNET_FLAG_NO_AUTH |
			INTERNET_FLAG_NO_COOKIES |
			INTERNET_FLAG_NO_UI |
			INTERNET_FLAG_RELOAD;
		if (0 < lstrlen(szExtraInfo))
		{
			lstrcat(szUrlPath, szExtraInfo);
		}

		// 以GET模式打開請(qǐng)求
		hRequest = HttpOpenRequest(hConnect, "GET", szUrlPath, NULL, NULL, NULL, dwOpenRequestFlags, 0);
		if (NULL == hRequest)
		{
			break;
		}

		// 發(fā)送請(qǐng)求
		bRet = HttpSendRequest(hRequest, NULL, 0, NULL, 0);
		if (FALSE == bRet)
		{
			break;
		}
		// 接收響應(yīng)的報(bào)文信息頭(Get Response Header)
		pResponseHeaderIInfo = new unsigned char[dwResponseHeaderIInfoSize];
		if (NULL == pResponseHeaderIInfo)
		{
			break;
		}
		RtlZeroMemory(pResponseHeaderIInfo, dwResponseHeaderIInfoSize);

		// 查詢HTTP請(qǐng)求頭
		bRet = HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, pResponseHeaderIInfo, &dwResponseHeaderIInfoSize, NULL);
		if (FALSE == bRet)
		{
			break;
		}

		// 從字符串中 "Content-Length: " 網(wǎng)頁(yè)獲取數(shù)據(jù)長(zhǎng)度
		bRet = GetContentLength((char*)pResponseHeaderIInfo, &dwDownloadDataSize);

		// 輸出完整響應(yīng)頭
		std::cout << pResponseHeaderIInfo << std::endl;
		if (FALSE == bRet)
		{
			break;
		}
		// 接收?qǐng)?bào)文主體內(nèi)容(Get Response Body)
		pBuf = new BYTE[dwBufSize];
		if (NULL == pBuf)
		{
			break;
		}
		pDownloadData = new BYTE[dwDownloadDataSize];
		if (NULL == pDownloadData)
		{
			break;
		}
		RtlZeroMemory(pDownloadData, dwDownloadDataSize);
		do
		{
			RtlZeroMemory(pBuf, dwBufSize);

			// 循環(huán)讀入數(shù)據(jù)并保存在變量中
			bRet = InternetReadFile(hRequest, pBuf, dwBufSize, &dwRet);
			if (FALSE == bRet)
			{
				break;
			}

			RtlCopyMemory((pDownloadData + dwOffset), pBuf, dwRet);
			dwOffset = dwOffset + dwRet;

		} while (dwDownloadDataSize > dwOffset);

		// 返回?cái)?shù)據(jù)
		*ppDownloadData = pDownloadData;
		*pdwDownloadDataSize = dwDownloadDataSize;

	} while (FALSE);

	// 關(guān)閉并釋放資源
	if (NULL != pBuf)
	{
		delete[]pBuf;
		pBuf = NULL;
	}
	if (NULL != pResponseHeaderIInfo)
	{
		delete[]pResponseHeaderIInfo;
		pResponseHeaderIInfo = NULL;
	}
	if (NULL != hRequest)
	{
		InternetCloseHandle(hRequest);
		hRequest = NULL;
	}
	if (NULL != hConnect)
	{
		InternetCloseHandle(hConnect);
		hConnect = NULL;
	}
	if (NULL != hInternet)
	{
		InternetCloseHandle(hInternet);
		hInternet = NULL;
	}
	return bRet;
}

// 創(chuàng)建并保存文件
BOOL SaveToFile(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;
}

使用時(shí)調(diào)用HttpDownload實(shí)現(xiàn)數(shù)據(jù)下載,下載后的文件會(huì)保存在pHttpDownloadData中,此時(shí)直接調(diào)用SaveToFile將其保存在文件中即可;

int main(int argc, char* argv[])
{
	// 設(shè)置需要下載的地址
	char szHttpDownloadUrl[] = "http://www.lyshark.com/index.html";
	BYTE* pHttpDownloadData = NULL;
	DWORD dwHttpDownloadDataSize = 0;

	// HTTP下載 
	if (TRUE == HttpDownload(szHttpDownloadUrl, &pHttpDownloadData, &dwHttpDownloadDataSize))
	{
		std::cout << "已保存文件,長(zhǎng)度: " << dwHttpDownloadDataSize << " 字節(jié)"<< std::endl;
	}

	// 將下載數(shù)據(jù)保存成文件
	SaveToFile((char *)"d://index.html", pHttpDownloadData, dwHttpDownloadDataSize);

	// 釋放內(nèi)存
	delete[]pHttpDownloadData;
	pHttpDownloadData = NULL;

	system("pause");
	return 0;
}

運(yùn)行后則可一輸出響應(yīng)頭Content-Length:完整參數(shù)以及輸出的字節(jié)數(shù),如下圖所示;

c++下載文件,《Visual C++ 編程技術(shù)實(shí)踐》,c語(yǔ)言,c++,http,文件上傳下載

上傳文件內(nèi)容

服務(wù)端,首先需要實(shí)現(xiàn)一個(gè)簡(jiǎn)單的上傳接收功能,這里使用flask框架實(shí)現(xiàn),通過(guò)執(zhí)行pip install flask命令安裝這個(gè)庫(kù),安裝成功以后手動(dòng)保存為main.py文件,上傳文件是只需要向http://127.0.0.1/upload?file=推送數(shù)據(jù)即可,代碼如下;

from flask import Flask, request

app = Flask(__name__)

@app.route('/upload', methods=['POST'])
def upload_file():
    file = request.args.get('file')
    
    if not file:
        return "上傳錯(cuò)誤,文件名未指定"

    try:
        with open(file, 'wb') as uploaded_file:
            uploaded_file.write(request.get_data())

        if os.path.exists(file):
            return "上傳成功"
        else:
            return "上傳失敗"
    except Exception as e:
        return f"上傳失敗: {str(e)}"

if __name__ == '__main__':
    app.run(debug=True, host='localhost', port=80)

服務(wù)端以管理員身份運(yùn)行main.py文件,此時(shí)會(huì)啟用一個(gè)Web服務(wù)器用于接收客戶端的上傳請(qǐng)求,如下圖所示;

c++下載文件,《Visual C++ 編程技術(shù)實(shí)踐》,c語(yǔ)言,c++,http,文件上傳下載

接著是客戶端的實(shí)現(xiàn),首先介紹如下幾個(gè)關(guān)鍵API函數(shù);

HttpSendRequestEx

用于發(fā)送帶有附加選項(xiàng)的 HTTP 請(qǐng)求。相對(duì)于 HttpSendRequest,它提供了更多的靈活性,允許在請(qǐng)求中包含額外的信息,例如頭部和數(shù)據(jù)。

以下是 HttpSendRequestEx 的原型:

BOOL HttpSendRequestEx(
  HINTERNET               hRequest,
  LPINTERNET_BUFFERS      lpBuffersIn,
  LPINTERNET_BUFFERS      lpBuffersOut,
  DWORD                   dwFlags,
  DWORD_PTR               dwContext
);

參數(shù)說(shuō)明:

  • hRequest:由 HttpOpenRequest 返回的句柄,表示 HTTP 請(qǐng)求。
  • lpBuffersIn:指向 INTERNET_BUFFERS 結(jié)構(gòu)的指針,其中包含要作為請(qǐng)求的一部分發(fā)送的數(shù)據(jù)。
  • lpBuffersOut:指向 INTERNET_BUFFERS 結(jié)構(gòu)的指針,用于接收響應(yīng)中接收到的數(shù)據(jù)。
  • dwFlags:附加標(biāo)志,控制函數(shù)的行為。這可以包括選項(xiàng),如 INTERNET_FLAG_RELOAD、INTERNET_FLAG_SECURE 等。
  • dwContext:傳遞給回調(diào)函數(shù)的用戶定義的上下文值。

INTERNET_BUFFERS 是一個(gè)結(jié)構(gòu),允許您在 HTTP 請(qǐng)求和響應(yīng)中指定用于發(fā)送和接收數(shù)據(jù)的緩沖區(qū)。

使用 HttpSendRequestEx 需要謹(jǐn)慎處理內(nèi)存,并根據(jù)您的需求設(shè)置 INTERNET_BUFFERS 結(jié)構(gòu)的具體方式。

InternetWriteFile

用于將數(shù)據(jù)寫入到由 InternetOpenUrlInternetOpen、HttpOpenRequestFtpOpenFile 等函數(shù)打開的 URL、連接或文件。以下是該函數(shù)的原型:

BOOL InternetWriteFile(
  HINTERNET hFile,
  LPCVOID   lpBuffer,
  DWORD     dwNumberOfBytesToWrite,
  LPDWORD   lpdwNumberOfBytesWritten
);

參數(shù)說(shuō)明:

  • hFile: 調(diào)用 InternetOpenUrl、InternetOpen、HttpOpenRequestFtpOpenFile 等函數(shù)返回的句柄,表示要寫入的文件、URL 或連接。
  • lpBuffer: 指向包含要寫入的數(shù)據(jù)的緩沖區(qū)的指針。
  • dwNumberOfBytesToWrite: 要寫入的字節(jié)數(shù)。
  • lpdwNumberOfBytesWritten: 指向一個(gè)變量,表示實(shí)際寫入的字節(jié)數(shù)。在調(diào)用函數(shù)前,應(yīng)該將該變量設(shè)置為緩沖區(qū)的大小。在調(diào)用函數(shù)后,該變量將包含實(shí)際寫入的字節(jié)數(shù)。

返回值:

如果函數(shù)調(diào)用成功,返回非零值;如果函數(shù)調(diào)用失敗,返回零??梢允褂?GetLastError 函數(shù)獲取詳細(xì)的錯(cuò)誤信息。

InternetWriteFile 主要用于將數(shù)據(jù)寫入網(wǎng)絡(luò)資源,如通過(guò) HTTP 或 FTP 協(xié)議上傳文件。在調(diào)用此函數(shù)之前,通常需要先調(diào)用其他相關(guān)的函數(shù),如 InternetOpenUrlInternetOpen、HttpOpenRequest 等。同樣,使用完資源后,需要使用 InternetCloseHandle 函數(shù)關(guān)閉相應(yīng)的句柄,以釋放資源。

HttpEndRequest

它通常與 HttpSendRequestHttpSendRequestEx 配合使用,用于完成 HTTP 請(qǐng)求的發(fā)送,并準(zhǔn)備接收服務(wù)器的響應(yīng)。

以下是 HttpEndRequest 函數(shù)的原型:

BOOL HttpEndRequest(
  HINTERNET hRequest,
  LPINTERNET_BUFFERS lpBuffersOut,
  DWORD dwFlags,
  DWORD_PTR dwContext
);

參數(shù)說(shuō)明:

  • hRequest: 調(diào)用 HttpOpenRequest、HttpOpenRequestEx、HttpSendRequestHttpSendRequestEx 等函數(shù)返回的 HTTP 請(qǐng)求句柄。
  • lpBuffersOut: 指向一個(gè) INTERNET_BUFFERS 結(jié)構(gòu)的指針,該結(jié)構(gòu)用于傳遞關(guān)于響應(yīng)數(shù)據(jù)的信息??梢詾?NULL。
  • dwFlags: 一些標(biāo)志,用于指定結(jié)束請(qǐng)求的選項(xiàng)。通常為 0。
  • dwContext: 用戶定義的應(yīng)用程序上下文,將在回調(diào)函數(shù)中使用。

返回值:

如果函數(shù)調(diào)用成功,返回非零值;如果函數(shù)調(diào)用失敗,返回零??梢允褂?GetLastError 函數(shù)獲取詳細(xì)的錯(cuò)誤信息。

HttpEndRequest 的主要作用是完成 HTTP 請(qǐng)求的發(fā)送,并在請(qǐng)求完成后準(zhǔn)備接收服務(wù)器的響應(yīng)。在調(diào)用此函數(shù)之后,通常會(huì)使用 InternetReadFile 函數(shù)等來(lái)讀取服務(wù)器的響應(yīng)數(shù)據(jù)。

上傳文件的完整代碼是這樣的,如下所示;

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

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

using namespace std;

// 切割路徑
BOOL UrlCrack(char* pszUrl, char* pszScheme, char* pszHostName, char* pszUserName, char* pszPassword, char* pszUrlPath, char* pszExtraInfo, DWORD dwBufferSize)
{
	BOOL bRet = FALSE;
	URL_COMPONENTS uc = { 0 };

	// 初始化變量中的內(nèi)容
	RtlZeroMemory(&uc, sizeof(uc));
	RtlZeroMemory(pszScheme, dwBufferSize);
	RtlZeroMemory(pszHostName, dwBufferSize);
	RtlZeroMemory(pszUserName, dwBufferSize);
	RtlZeroMemory(pszPassword, dwBufferSize);
	RtlZeroMemory(pszUrlPath, dwBufferSize);
	RtlZeroMemory(pszExtraInfo, dwBufferSize);

	// 將長(zhǎng)度填充到結(jié)構(gòu)中
	uc.dwStructSize = sizeof(uc);
	uc.dwSchemeLength = dwBufferSize - 1;
	uc.dwHostNameLength = dwBufferSize - 1;
	uc.dwUserNameLength = dwBufferSize - 1;
	uc.dwPasswordLength = dwBufferSize - 1;
	uc.dwUrlPathLength = dwBufferSize - 1;
	uc.dwExtraInfoLength = dwBufferSize - 1;
	uc.lpszScheme = pszScheme;
	uc.lpszHostName = pszHostName;
	uc.lpszUserName = pszUserName;
	uc.lpszPassword = pszPassword;
	uc.lpszUrlPath = pszUrlPath;
	uc.lpszExtraInfo = pszExtraInfo;

	// 分解URL地址
	bRet = InternetCrackUrl(pszUrl, 0, 0, &uc);
	if (FALSE == bRet)
	{
		return bRet;
	}
	return bRet;
}

// 從響應(yīng)信息頭信息中獲取數(shù)據(jù)內(nèi)容長(zhǎng)度大小
BOOL GetContentLength(char* pResponseHeader, DWORD* pdwContentLength)
{
	int i = 0;
	char szContentLength[MAX_PATH] = { 0 };
	DWORD dwContentLength = 0;
	char szSubStr[] = "Content-Length: ";
	RtlZeroMemory(szContentLength, MAX_PATH);

	// 在傳入字符串中查找子串
	char* p = strstr(pResponseHeader, szSubStr);
	if (NULL == p)
	{
		return FALSE;
	}

	p = p + lstrlen(szSubStr);

	// 如果找到了就提取出里面的純數(shù)字
	while (('0' <= *p) && ('9' >= *p))
	{
		szContentLength[i] = *p;
		p++;
		i++;
	}

	// 字符串轉(zhuǎn)數(shù)字
	dwContentLength = atoi(szContentLength);
	*pdwContentLength = dwContentLength;
	return TRUE;
}

// 數(shù)據(jù)上傳
BOOL HttpUpload(char* pszUploadUrl, BYTE* pUploadData, DWORD dwUploadDataSize)
{
	// 初始化變量中的內(nèi)容
	char szScheme[MAX_PATH] = { 0 };
	char szHostName[MAX_PATH] = { 0 };
	char szUserName[MAX_PATH] = { 0 };
	char szPassword[MAX_PATH] = { 0 };
	char szUrlPath[MAX_PATH] = { 0 };
	char szExtraInfo[MAX_PATH] = { 0 };
	
	// 將長(zhǎng)度填充到結(jié)構(gòu)中
	RtlZeroMemory(szScheme, MAX_PATH);
	RtlZeroMemory(szHostName, MAX_PATH);
	RtlZeroMemory(szUserName, MAX_PATH);
	RtlZeroMemory(szPassword, MAX_PATH);
	RtlZeroMemory(szUrlPath, MAX_PATH);
	RtlZeroMemory(szExtraInfo, MAX_PATH);
	
	// 分解URL地址
	if (FALSE == UrlCrack(pszUploadUrl, szScheme, szHostName, szUserName, szPassword, szUrlPath, szExtraInfo, MAX_PATH))
	{
		return FALSE;
	}

	// 數(shù)據(jù)上傳
	HINTERNET hInternet = NULL;
	HINTERNET hConnect = NULL;
	HINTERNET hRequest = NULL;
	DWORD dwOpenRequestFlags = 0;
	BOOL bRet = FALSE;
	DWORD dwRet = 0;
	unsigned char* pResponseHeaderIInfo = NULL;
	DWORD dwResponseHeaderIInfoSize = 2048;
	BYTE* pBuf = NULL;
	DWORD dwBufSize = 64 * 1024;
	BYTE* pResponseBodyData = NULL;
	DWORD dwResponseBodyDataSize = 0;
	DWORD dwOffset = 0;
	DWORD dwPostDataSize = dwUploadDataSize;
	INTERNET_BUFFERS internetBuffers = { 0 };

	do
	{
		// 建立會(huì)話
		hInternet = InternetOpen("WinInetPost/0.1", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
		if (NULL == hInternet)
		{
			break;
		}

		// 建立連接
		hConnect = InternetConnect(hInternet, szHostName, INTERNET_DEFAULT_HTTP_PORT, szUserName, szPassword, INTERNET_SERVICE_HTTP, 0, 0);
		if (NULL == hConnect)
		{
			break;
		}

		// 打開并發(fā)送HTTP請(qǐng)求
		dwOpenRequestFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
			INTERNET_FLAG_KEEP_CONNECTION |
			INTERNET_FLAG_NO_AUTH |
			INTERNET_FLAG_NO_COOKIES |
			INTERNET_FLAG_NO_UI |
			INTERNET_FLAG_RELOAD;
		if (0 < lstrlen(szExtraInfo))
		{
			lstrcat(szUrlPath, szExtraInfo);
		}

		// 使用POST請(qǐng)求
		hRequest = HttpOpenRequest(hConnect, "POST", szUrlPath, NULL, NULL, NULL, dwOpenRequestFlags, 0);
		if (NULL == hRequest)
		{
			break;
		}

		// 告訴服務(wù)器傳輸數(shù)據(jù)的總大小
		RtlZeroMemory(&internetBuffers, sizeof(internetBuffers));
		internetBuffers.dwStructSize = sizeof(internetBuffers);
		internetBuffers.dwBufferTotal = dwPostDataSize;

		bRet = HttpSendRequestEx(hRequest, &internetBuffers, NULL, 0, 0);
		if (FALSE == bRet)
		{
			break;
		}

		// 發(fā)送數(shù)據(jù)
		bRet = InternetWriteFile(hRequest, pUploadData, dwUploadDataSize, &dwRet);
		if (FALSE == bRet)
		{
			break;
		}

		// 發(fā)送完畢
		bRet = HttpEndRequest(hRequest, NULL, 0, 0);
		if (FALSE == bRet)
		{
			break;
		}

		// 接收響應(yīng)報(bào)文
		pResponseHeaderIInfo = new unsigned char[dwResponseHeaderIInfoSize];
		if (NULL == pResponseHeaderIInfo)
		{
			break;
		}
		RtlZeroMemory(pResponseHeaderIInfo, dwResponseHeaderIInfoSize);
		bRet = HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, pResponseHeaderIInfo, &dwResponseHeaderIInfoSize, NULL);
		if (FALSE == bRet)
		{
			break;
		}

		// 獲取數(shù)據(jù)長(zhǎng)度
		bRet = GetContentLength((char*)pResponseHeaderIInfo, &dwResponseBodyDataSize);
		if (FALSE == bRet)
		{
			break;
		}

		// 輸出響應(yīng)頭
		std::cout << pResponseHeaderIInfo << std::endl;

		// 接收?qǐng)?bào)文主體內(nèi)容(Get Response Body)
		pBuf = new BYTE[dwBufSize];
		if (NULL == pBuf)
		{
			break;
		}
		pResponseBodyData = new BYTE[dwResponseBodyDataSize];
		if (NULL == pResponseBodyData)
		{
			break;
		}
		RtlZeroMemory(pResponseBodyData, dwResponseBodyDataSize);

		do
		{
			// 循環(huán)讀取數(shù)據(jù)并填充到緩沖區(qū)內(nèi)
			RtlZeroMemory(pBuf, dwBufSize);
			bRet = InternetReadFile(hRequest, pBuf, dwBufSize, &dwRet);
			if (FALSE == bRet)
			{
				break;
			}

			RtlCopyMemory((pResponseBodyData + dwOffset), pBuf, dwRet);
			dwOffset = dwOffset + dwRet;

		} while (dwResponseBodyDataSize > dwOffset);

	} while (FALSE);

	// 關(guān)閉釋放
	if (NULL != pResponseBodyData)
	{
		delete[]pResponseBodyData;
		pResponseBodyData = NULL;
	}
	if (NULL != pBuf)
	{
		delete[]pBuf;
		pBuf = NULL;
	}
	if (NULL != pResponseHeaderIInfo)
	{
		delete[]pResponseHeaderIInfo;
		pResponseHeaderIInfo = NULL;
	}

	if (NULL != hRequest)
	{
		InternetCloseHandle(hRequest);
		hRequest = NULL;
	}
	if (NULL != hConnect)
	{
		InternetCloseHandle(hConnect);
		hConnect = NULL;
	}
	if (NULL != hInternet)
	{
		InternetCloseHandle(hInternet);
		hInternet = NULL;
	}

	return bRet;
}

上傳代碼通過(guò)指定szHttpUploadUrld://lyshark.exe文件提交到遠(yuǎn)程主機(jī),代碼如下所示;

int main(int argc, char* argv[])
{
	// 設(shè)置上傳接口地址
	char szHttpUploadUrl[] = "http://127.0.0.1/upload?file=lyshark.exe";

	// 被上傳文件絕對(duì)路徑
	char szHttpUploadFileName[] = "d://lyshark.exe";
	BYTE* pHttpUploadData = NULL;
	DWORD dwHttpUploadDataSize = 0;
	DWORD dwRet = 0;
	
	// 打開文件
	HANDLE hFile = CreateFile(szHttpUploadFileName, GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
		FILE_ATTRIBUTE_ARCHIVE, NULL);

	// 獲取文件大小
	dwHttpUploadDataSize = GetFileSize(hFile, NULL);
	
	// 讀取文件數(shù)據(jù)
	pHttpUploadData = new BYTE[dwHttpUploadDataSize];
	ReadFile(hFile, pHttpUploadData, dwHttpUploadDataSize, &dwRet, NULL);
	dwHttpUploadDataSize = dwRet;
	
	// 上傳數(shù)據(jù)
	if (FALSE == HttpUpload(szHttpUploadUrl, pHttpUploadData, dwHttpUploadDataSize))
	{
		return 0;
	}

	// 釋放內(nèi)存
	delete[]pHttpUploadData;
	pHttpUploadData = NULL;
	CloseHandle(hFile);

	system("pause");
	return 0;
}

運(yùn)行后提交文件,則可以看到輸出信息,如下圖所示;

c++下載文件,《Visual C++ 編程技術(shù)實(shí)踐》,c語(yǔ)言,c++,http,文件上傳下載文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-826964.html

到了這里,關(guān)于C/C++ 通過(guò)HTTP實(shí)現(xiàn)文件上傳下載的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • MINIO服務(wù)器基于AWS S3 SDK 文件分片上傳及下載(C++實(shí)現(xiàn))

    MINIO服務(wù)器基于AWS S3 SDK 文件分片上傳及下載(C++實(shí)現(xiàn))

    安裝環(huán)境依賴: 獲取SDK源碼并安裝: 項(xiàng)目中CMakeLists.txt配置: SDK文檔資料 C++_SDK.pdf 實(shí)現(xiàn)下載的整體類代碼下載 具體內(nèi)容如下

    2024年04月10日
    瀏覽(51)
  • JAVA Http接口獲取文件下載流,將下載的文件上傳阿里云

    ?需要根據(jù),業(yè)務(wù)數(shù)據(jù),將存在第三方平臺(tái)的數(shù)據(jù),下載至本地,或轉(zhuǎn)存阿里云OSS中。

    2024年02月16日
    瀏覽(30)
  • linux文件通過(guò)finalshell的上傳和下載

    linux文件通過(guò)finalshell的上傳和下載

    我們可以通過(guò)finalshell工具,方便的和虛擬機(jī)進(jìn)行數(shù)據(jù)交換 在finalshell下方的窗口中,提供了linux文件系統(tǒng)視圖: 瀏覽文件系統(tǒng),找到合適的文件,右鍵點(diǎn)擊下載,即可傳輸?shù)奖镜仉娔X 瀏覽文件系統(tǒng),找到合適的目錄,將本地電腦的文件拖拽進(jìn)入,即可方便的上傳數(shù)據(jù)到linux中

    2024年02月11日
    瀏覽(15)
  • [Python http.server] 搭建http服務(wù)器用于下載/上傳文件

    [Python http.server] 搭建http服務(wù)器用于下載/上傳文件

    動(dòng)機(jī): 筆者需測(cè)試bs架構(gòu)下的文件上傳與下載性能,故想通過(guò)Python搭建http服務(wù)器并實(shí)現(xiàn)客戶端與服務(wù)器之間的文件上傳和下載需求 難點(diǎn): 這應(yīng)該是很基礎(chǔ)的東西,不過(guò)筆者之前未接觸過(guò)http編程,謹(jǐn)在此記錄下學(xué)習(xí)的過(guò)程,可能不是最優(yōu)解 方法: 在服務(wù)器端部署html頁(yè)面,并

    2024年02月11日
    瀏覽(18)
  • Python(35):Python3 通過(guò)https上傳文件和下載文件

    Python http方式的下載,參考:https://blog.csdn.net/fen_fen/article/details/113753983 https需要先安裝需要的模塊 1.1、調(diào)用: 1.2、上傳代碼 ?2.1、下載調(diào)用: 2.2、Python3 https下載文件工具類:

    2024年01月23日
    瀏覽(20)
  • 三分鐘用Golang搭建一個(gè)HTTP文件上傳下載服務(wù)器

    三分鐘用Golang搭建一個(gè)HTTP文件上傳下載服務(wù)器

    簡(jiǎn)單需要一個(gè)文件服務(wù)器來(lái)傳遞數(shù)據(jù),只要兩個(gè)功能,一個(gè)上傳接口,一個(gè)下載接口。 選用go http模塊實(shí)現(xiàn),比nginx、ftp等更方便快捷。 上傳接口\\\"/v1/file_upload/\\\" 上傳接口增加簡(jiǎn)單BasicAuth鑒權(quán) 上傳成功返回下載URL json格式返回 只想文件上傳服務(wù)器測(cè)試接口,以下電梯直達(dá)即可

    2024年02月11日
    瀏覽(24)
  • Java實(shí)現(xiàn)HTTP的上傳與下載

    相信很多人對(duì)于java文件下載的過(guò)程都存在一些疑惑,比如下載上傳文件會(huì)不會(huì)占用vm內(nèi)存,上傳/下載大文件會(huì)不會(huì)導(dǎo)致oom。下面從字節(jié)流的角度看下載/上傳的實(shí)現(xiàn),可以更加深入理解文件的上傳和下載功能。 首先明確,文件下載不僅僅只有下載方,還有服務(wù)端也就是返回文

    2024年02月10日
    瀏覽(17)
  • 調(diào)用hutool包調(diào)用http接口處理文件流-文件的上傳下載工具類

    hutool工具類get請(qǐng)求獲取流: InputStream inputStream = HttpRequest.get(fileUrl).execute().bodyStream(); hutool工具類post請(qǐng)求上傳文件流: String resp = HttpRequest.post(url).header(Header.CONTENT_TYPE.getValue(), ContentType.MULTIPART.getValue()).form(params).execute().body(); 完成代碼

    2024年01月17日
    瀏覽(27)
  • 前端通過(guò)STS方式直傳至阿里云OSS(包含文件上傳、下載和自動(dòng)刷新stsToken)

    最近項(xiàng)目業(yè)務(wù)需要實(shí)現(xiàn)一個(gè)資源管理的功能,就簡(jiǎn)單學(xué)習(xí)了一下前端怎么使用阿里云OSS。 原本這些事情都是后端實(shí)現(xiàn)的,但這樣子有許多缺點(diǎn),比如文件上傳需要走兩次,先上傳到后端,再由后端上傳至阿里云OSS,既占用帶寬也浪費(fèi)時(shí)間;此外,前端還不能獲取到真正的上傳

    2024年01月19日
    瀏覽(31)
  • 文件上傳下載系列——如何實(shí)現(xiàn)文件秒傳

    文件上傳下載系列——如何實(shí)現(xiàn)文件秒傳

    ??簡(jiǎn)介: ??核心思想: MD5是什么? 實(shí)現(xiàn)步驟: ??實(shí)操: 1、java生成文件MD5碼 2、javascript生成文件MD5碼 ??基于秒傳的分片上傳下載 上傳: 下載: ??MD5存儲(chǔ)位置 1、持久化到數(shù)據(jù)庫(kù)中 2、存儲(chǔ)到redis中 ??總結(jié) ????????文件秒傳是指在文件上傳過(guò)程中,如果上傳的文件

    2024年02月01日
    瀏覽(35)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包