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 后值是一样的,那我们下载的文件就是正常的。文章来源:https://www.toymoban.com/news/detail-488008.html
文章来源地址https://www.toymoban.com/news/detail-488008.html
到了这里,关于http 协议大文件下载的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!