Qt中使用Http通讯下载文件

目录

前提

HTTP通讯下载

请求http文件

分解URL网址

创建会话

创建连接

创建请求

发送请求

接收http请求响应

文件操作

获取文件长度

实时下载文件

总结


前提

在某些功能中,会使用到通过Http通讯从网址上下载资源信息。

在这里,我说的资源信息是指以.png、.mp4以及.doc为后缀的文件。只是做一个简单的功能实现。

需要实现的功能:根据网址url将文件下载到指定位置,并实时显示下载进度。

HTTP通讯下载

下载文件,首先需要将文件下载下来。

为了方便使用,一般情况下,我们会将接口设置成简单明了的形式。

这里,我们设置了三个参数

int HttpDownLoad(int enumType, std::string strRemoteFile, std::string strLocalFile);

参数讲解:

enumType:当前表示下载的方式,是http?https

strRemoteFile:url的完整路径

strLocalFile:下载到指定位置的全路径

我们在使用过程中,对外开放这一个接口,就完全可以实现下载功能啦!

请求http文件

对于HTTP的使用,无外乎就是这样一个流程:创建会话,建立连接,建立请求,数据操作

对于下载功能来说,在创建会话之前,需要分析传入的url网址。

分解URL网址

使用WinHttpCrackUrl方式,可以将一个给定的url分解,设置到**URL_COMPONENTS**这个结构体中。

这一步骤是必须要操作的!

URL_INFO url_info = { 0 };
URL_COMPONENTSW lpUrlComponents = { 0 };
lpUrlComponents.dwStructSize = sizeof(lpUrlComponents);
lpUrlComponents.lpszExtraInfo = url_info.szExtraInfo;
lpUrlComponents.lpszHostName = url_info.szHostName;
lpUrlComponents.lpszPassword = url_info.szPassword;
lpUrlComponents.lpszScheme = url_info.szScheme;
lpUrlComponents.lpszUrlPath = url_info.szUrlPath;
lpUrlComponents.lpszUserName = url_info.szUserName;

lpUrlComponents.dwExtraInfoLength = 512;
lpUrlComponents.dwHostNameLength = 512;
lpUrlComponents.dwPasswordLength = 512;
lpUrlComponents.dwSchemeLength = 512;
lpUrlComponents.dwUrlPathLength = 512;
lpUrlComponents.dwUserNameLength = 512;

if (!WinHttpCrackUrl(strRemoteFile, 0, ICU_ESCAPE, &lpUrlComponents))
{
	return GetLastError();
}

说明:这里需要注意的是512,如果你的url网址太长了,需要修改这个数值。否则会产生错误!

创建会话

对于一个应用程序,WinHttpOpen函数初始化WinHTTP函数的使用,并返回一个WinHTTP会话句柄。

// 创建一个会话
HINTERNET hSession = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, NULL);

参数说明:

参数1:一个指向字符串变量的指针,该变量包含调用WinHTTP函数的应用程序或实体的名称。一般我们会采用null使用。

参数2:利用默认的代办服务器

参数3:如果参数2未设置为WINHTTP_ACCESS_TYPE_NAMED_PROXY,则此参数必须设置为WINHTTP_NO_PROXY_NAME。

参数4:如果参数2未设置为“WINHTTP_ACCESS_TYPE_NAMED_PROXY”,该参数必须设置“WINHTTP_NO_PROXY_BYPASS”

参数5:一般采用null

创建连接

WinHttpConnect函数指定HTTP请求的初始目标服务器,并为该初始目标返回一个HTTP会话的HINTERNET连接句柄。

HINTERNET hConnect = WinHttpConnect(hSession, lpUrlComponents.lpszHostName, lpUrlComponents.nPort, 0);

参数说明:

参数1:WinHttpOpen的返回参数

参数2:该字符串包含HTTP服务器的主机名

参数3:该字符串包含HTTP服务器的端口号

参数4:该参数为保留参数,且必须为0!!!

创建请求

在创建请求时,我们需要注意,这里要根据是http通讯还是https通讯设置不同的标识。

if (enumType == HttpType_HTTP)
{
	dwFlags = WINHTTP_FLAG_REFRESH;
}
else if (enumType == HttpType_HTTPS)
{
	dwFlags = WINHTTP_FLAG_REFRESH | WINHTTP_FLAG_SECURE;
}

WinHttpOpenRequest函数创建一个HTTP请求句柄。

HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", lpUrlComponents.lpszUrlPath, L"HTTP/1.1", WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, dwFlags);
if (enumType == HttpType_HTTPS)
{
	DWORD  dwFlags = SECURITY_FLAG_IGNORE_UNKNOWN_CA |
		SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE |
		SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
		SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
	//设置支持https
	if (!WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwFlags, sizeof(dwFlags)))
	{
		return GetLastError();
	}
}

发送请求

WinHttpSendRequest函数向HTTP服务器发送指定的请求。

if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
{
	return GetLastError();
}

参数说明:

参数1:是WinHttpOpenRequest的句柄

参数2:如果没有附加的头文件,这个参数可以是WINHTTP_NO_ADDITIONAL_HEADERS。

参数3:一个无符号长整数值,包含附加头的字符长度。如果该参数为-1L且pwszHeaders不为NULL,则该函数假设pwszHeaders为NULL结束,并计算其长度。一般我们只用0代替就可以了。

参数4:如果没有可选的数据要发送,这个参数可以是WINHTTP_NO_REQUEST_DATA。

参数5:如果没有可选数据要发送,此参数可以为零。

参数6:发送的总数据的长度

参数7:指针指向一个指针大小的变量,该变量包含一个应用程序定义的值,该值与请求句柄一起传递给任何回调函数。这里默认是0即可。

接收http请求响应

WinHttpReceiveResponse函数等待接收由WinHttpSendRequest发起的HTTP请求的响应

当winhttpreceiverresponse成功完成时,状态码和响应头已经被接收,应用程序可以使用WinHttpQueryHeaders来检查。

if (!WinHttpReceiveResponse(hRequest, 0))
{
	return GetLastError();
}

到这里我们就可以获取文件的长度了!

文件操作

获取文件长度

DWORD dwContentSize = 0, dwIndex = 0, dwSizeDW = sizeof(dwSizeDW);
WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwContentSize, &dwSizeDW, &dwIndex);

根据获取的文件长度,创建一个本地文件进行存储数据了。

实时下载文件

WinHttpQueryDataAvailable函数返回可用WinHttpReadData读取的数据量(以字节为单位)。

使用while循环的方式,逐字节获取,并实时写入到文件中

DWORD  dwSize, dwWrite, dwCalcSize = 0;
while (WinHttpQueryDataAvailable(hRequest, &dwSize) && dwSize)
{
	ZeroMemory(pBuffer, 4096);
	WinHttpReadData(hRequest, pBuffer, dwSize, &dwSize);
	WriteFile(hFile, pBuffer, dwSize, &dwWrite, NULL);
}

最后,数据写完之后,关闭文件,并关闭http通讯!

总结

看到这里,使用http通讯方式下载文件就完成了。

难点1:在下载https文件时,会有证书的问题,不过没关系,这种验证方式我已经说明了,只要按照我的方式肯定可以获取到,前提是你的证书必须要合法,否则我也无法帮助你啦!

难点2:下载文件时,一定要先创建文件路径,再存储。最好采用CreateFile的方式。


今天的更新就到这里喽~

我是糯诺诺米团,一名C++开发程序媛~

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Qt是一种跨平台的应用程序开发框架,可以使用C++编程语言进行开发。BLE是低功耗蓝牙技术,用于设备之间的无线通信。在使用Qt进行BLE设备通讯时,可以通过以下步骤进行代码下载使用: 第一步,确保已下载并安装了Qt开发环境,并且系统已连接到BLE设备。可以使用Qt Creator作为集成开发环境。 第二步,创建一个新的Qt项目。在Qt Creator选择“新建项目”,选择Qt Quick应用程序或者其他适合的项目类型。填写项目名称和位置,点击“下一步”。 第三步,在项目配置页面,选择目标平台和构建套件。点击“下一步”,完成项目配置。 第四步,在项目主文件(通常是main.cpp或者main.qml),添加BLE设备通讯的代码。根据具体的需求,可以使用Qt提供的BLE库或者其他第三方库进行BLE设备通讯。 第五步,编写BLE设备通讯的相关代码。这些代码包括扫描BLE设备、连接BLE设备、读取和写入BLE设备的特征值等操作。根据具体的需求,可以参考Qt的官方文档或者其他资源进行开发。 第六步,构建和运行项目。在Qt Creator点击构建按钮,等待编译完成后点击运行按钮。如果一切正常,项目将会运行并与BLE设备进行通讯。 需要注意的是,BLE设备通讯的代码下载使用会受到设备和操作系统的限制。在编写代码之前,需要了解设备和操作系统的相关要求和限制,并进行相应的适配。 总之,通过Qt开发环境,我们可以方便地进行BLE设备通讯的代码下载使用。通过逐步完成上述步骤,我们可以在Qt轻松地实现与BLE设备的通讯

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糯诺诺米团

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值