http 协议大文件下载

17 篇文章 3 订阅
11 篇文章 0 订阅

        http 协议的响应报文格式包括起始行+头部字段+响应正文,其格式为:

/*严格按照http应答头格式进行填写:如果有正文,需要在头部字段里写明

** 协议版本|空格|状态码|空格|状态码描述|回车|换行
** 头部字段名|冒号|字段值|回车|换行
** 头部字段名|冒号|字段值|回车|换行
** 头部字段名|冒号|字段值|回车|换行
** .....
** 回车|换行
** 响应正文

*/

        响应的正文只能通过http响应消息进行传输,如果是小文件(比如小于1M)传输,则没有什么问题,直接把文件内容加载到正文进行回应即可,但如果是大文件(比如大于10M),不可能把文件内容加载到正文吧,如果更大的文件呢,100M?

        http 协议的 Transfer-Encoding: chunked 传输方式可以解决文件大小未知的情况(大文件我们也可以当作其大小未知来处理),客户端支持 chunked 传输的情况下,会将服务端发送过来的 n 个 chunked 进行重组,最后形成文件,这种传输方式有格式限制,假如出错的话,客户端可能会一直等待(因为它不知道什么时候结束),其格式如下:

/* chunked 传输方式格式

** 协议版本|空格|状态码|空格|状态码描述|回车|换行
** 头部字段名|冒号|字段值|回车|换行
** 头部字段名|冒号|字段值|回车|换行
** 头部字段名|冒号|字段值|回车|换行
** 
** n1大小|换行
** 响应正文
**
** n2大小|换行
** 响应正文
**
** n2大小|换行
** 响应正文
**
** 0|换行
*/

更形象如下:

需要注意:响应头只需要一条,而 chunked 则可以是多条,看你将文件分为多少块了,响应头必须要有 "Transfer-Encoding: chunked"。

那用c++代码怎么写呢?主要代码片段如下:

//处理大文件,采用分块传输的方式
std::string headers;
headers.append("HTTP/1.1 200 ok").append("\r\n");
response.getHead(headers);
headers.append("Content-Type: application/octet-stream").append("\r\n");
headers.append("Transfer-Encoding: chunked").append("\r\n").append("\r\n");

mg_send(connection, headers.c_str(), headers.length());
tracef("giant file send header: %s\n", headers.c_str());

sendGiantFile(connection, fileName.c_str());

 最主要就是下面这个函数:

void sendGiantFile(struct mg_connection *connection, const char *fileName)
{
    size_t fileLen = 0;
    int readLen = 0;
    char buf[4096] = {0};
    FILE *fp = fopen(fileName, "r");
    fseek(fp, 0, SEEK_END);
    fileLen = ftell(fp);
    rewind(fp);

    while(fileLen > 0)
    {   
        readLen = fread(buf, 1, sizeof(buf), fp);
        mg_send_http_chunk(connection, buf, readLen);
        fileLen -= readLen;
    }

    fclose(fp);

    //最后0结尾
    tracef("send tail 0 chunked\n");
    mg_send_http_chunk(connection, "", 0);
}

当发送响应头之后 ,用一个 while 循环进行文件块的发送,每次发送大小自行决定,这里用到的是mongoose 里的接口 mg_send_http_chunk() 函数,最后发送一个0及\r\n 表示 chunk 传输结束。其实际效果为:

下载一个 19 M 的文件是可以成功的,再大的文件没有试,因为下载速度有点慢。那下载下来的文件是否有异常呢?我们可以看一下原文件和下载的文件经过 md5 编码是否一样就可以了。

原文件 md5 码:

 设备上已经有 md5sum 命令,直接使用了。

下载文件的 md5 码:

windows上下载的,所以把这个文件拷贝到 CentOS 服务上看一下了,这两个文件经过 md5sum 后值是一样的,那我们下载的文件就是正常的。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: VC是指Visual C++,而http协议是一种用于传输超文本的协议。在VC中使用http协议下载文件可以通过以下步骤实现。 首先,需要使用VC提供的网络编程库,如WinINet或WinHTTP。这些库提供了一些函数和类,用于与服务器进行http通信。 其次,需要创建一个http会话并与服务器建立连接。这可以通过调用相关函数来实现,如InternetOpen、InternetConnect等。 然后,要使用http协议发送下载文件的请求。可以使用HTTP GET方法向服务器发送请求,并指定要下载文件的URL。这可以通过调用相关函数,如HttpOpenRequest、HttpSendRequest等来实现。 接下来,需要接收服务器的响应并获取待下载文件的信息,如文件大小、文件类型等。可以使用相关函数如HttpQueryInfo等来实现。 然后,创建本地文件并准备接收服务器发送的文件内容。可以使用相关函数如CreateFile、WriteFile等来实现。 最后,从服务器接收文件内容并将其写入本地文件中。这可以通过调用相关函数如InternetReadFile等来实现,直到接收完整个文件。 需要注意的是,在下载过程中需要严密地处理各种可能的错误和异常情况,以确保下载过程的稳定性和可靠性。 以上是使用VC中http协议下载文件的大致步骤,具体的实现细节可以根据具体情况和需求进行调整和完善。 ### 回答2: VC(Virtual Channel)是在计算机网络中用于传输数据的通道,它是一种在网络服务器和客户端之间建立连接并传输数据的协议HTTP(Hypertext Transfer Protocol)是一种用于在网络上传输超文本的协议。 在使用VC协议下载文件时,通常会结合HTTP协议来完成文件的传输。具体的步骤如下: 1. 客户端向服务器发送HTTP请求,请求下载文件的URL。 2. 服务器接收到请求后,通过VC协议建立与客户端的连接,并开始传输文件。 3. 服务器根据请求的URL找到对应的文件,并以HTTP响应的形式返回给客户端。 4. 客户端接收到服务器的响应后,开始通过VC协议接收文件数据。 5. 服务器通过VC协议文件数据分包发送给客户端,客户端通过接收这些包来获取完整的文件数据。 6. 当服务器传输完整个文件后,关闭与客户端的连接。 通过以上步骤,客户端就能够使用VC协议下载HTTP协议中请求的文件。VC协议通过在网络上建立可靠的连接来确保数据的完整性和准确性。而HTTP协议则负责处理客户端和服务器之间的通信,并提供对文件的请求和响应。 总结起来,通过VC和HTTP协议的结合,实现了在网络上下载文件的功能,使得文件的传输更加可靠和高效。 ### 回答3: VC是Visual C++的简称,是一种面向对象的编程语言。VC可以使用HTTP协议下载文件,以下是下载文件的步骤: 1. 创建一个Win32控制台应用程序的工程,打开VC开发环境。 2. 在代码中引入必要的头文件,如 <winhttp.h> 和 <iostream>。 3. 使用WinHTTP库进行HTTP请求,可以使用WinHttpOpen函数初始化HTTP会话,然后使用WinHttpOpenRequest函数创建HTTP请求。 4. 设置HTTP请求的参数,包括请求的method(GET或POST),URL、头部信息等。 5. 发送HTTP请求,使用WinHttpSendRequest函数发送请求到服务器。 6. 接收HTTP响应,使用WinHttpReceiveResponse函数接收服务器的响应。 7. 判断响应状态,使用WinHttpQueryHeaders函数查询响应头部信息,判断请求是否成功。 8. 创建本地文件,使用CreateFile函数创建保存文件的本地文件。 9. 读取响应数据,使用WinHttpReadData函数持续读取服务器返回的数据,并写入本地文件。 10. 关闭HTTP请求和会话,使用WinHttpCloseHandle函数关闭请求和会话句柄。 11. 关闭本地文件,使用CloseHandle函数关闭本地文件句柄。 以上是使用VC编写的HTTP协议下载文件的基本过程。在实际应用中,还可以添加错误处理、进度显示等功能,以提高用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值