本篇博文将介绍几个我认为比较有作用的请求部首

Connection ,这个部首常见的值是keep-alive 和close。close的意思是说,我发一次请求,你回复给我消息,那么咱俩就立刻断开,等我下次想请求数据时,我会再次发起tcp连接。而keep-alive的意思是说,这一次,咱俩好不容易建立起连接,不要那么快断开,多保持一段时间,我还有很多请求要发送呢。当你看到这篇文章时,浏览器里只有一个地址,但是你可不要以为浏览器只向服务器发送了一次请求就拿到了整个网页。这网页里还有许多其他的资源,比如css,js都是需要加载的,那么这些都需要浏览器向服务器发送请求。如果每一次请求完毕后都断开连接,那么下一次就需要重新发起连接。这样对双方来说都很糟糕,因为建立TCP连接是需要耗费资源的,因此就有了keep-alive,如果服务器支持这种方式,那么双方就可以建立起长连接

Referer,  网页里存在大量的连接,我们点击后就会跳转到别的网页,比如,你在A网页中点击了一个网页跳转到了B网页,那么这时,请求B网页的请求头部首中就会有Referer这个字段,这个字段里记录的是A网页的地址,说白了,就是告诉服务器,我们是从哪里跳转过来的。这个东西还是蛮有作用的,通过分析Referer,我们就能知道用户是经过什么样的途径来到我们的网站的,这对于电子商务网站来说有着很重要的数据挖掘价值。

Range,我们向服务器请求资源时,可以明确的告知,我们请求的是哪一部分,比如一个下载的文件有4M大小,那么浏览器可以发出4个请求,分别请求1M大小的数据,这时就需要告诉服务器,本次请求的资源时哪个范围内的,举例:Range: bytes = 500 -1500,这个部首的意思就是说,请求资源的第500到1500byte的内容。对于小文件来说,其实没有啥必要,但是对于很大的文件来说,这就显得非常有必要了,如果能分块请求,那么即便其中一块出了啥问题,其他的部分不需要重新下载的,只需要重新请求出问题的那块就可以了。

User-Agent,这个部首会提供一些关于客户端的信息,比如用的什么操作系统,用的什么浏览器,通过这个部首,理论上可以区分请求是来自于PC还是智能手机

OK,已经介绍了四个请求部首,下面说说如何用c++发起socket请求下载文件

首先,找到一个可用的下载资源 http://f1.market.xiaomi.com/download/AppStore/0831c047a8a8e

4cff181d1466c39f5d4145402b80/com.julanling.app.apk,

打开cmd命令窗口 ping f1.market.xiaomi.com ,这样就可以获得它的IP地址,我这里获得是106.38.211.3,不同的人可能获取的不一样,但是没关系,之所以会这样,是因为网站太大了,用的是服务器集群,所以DNS会解析出多个IP地址,但是每一个都可以使用。现在,我们已经知道了IP地址,端口默认80,也知道了host和 request-URL,那么我们就可以向服务器发送请求了,贴上代码

#include<iostream>
#include<WinSock2.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
//http://f1.market.xiaomi.com/download/AppStore/0831c047a8a8e4cff181d1466c39f5d4145402b80/com.julanling.app.apk
const int BuffSize = 1024;
void downLoad(){WSADATA WsaData;if (WSAStartup(MAKEWORD(2,2),&WsaData)){printf("初始化失败");return ;}SOCKET sockeId;SOCKADDR_IN addr;if (-1 == (sockeId = socket(AF_INET, SOCK_STREAM, 0))){printf("创建socket失败");return;}addr.sin_addr.S_un.S_addr = inet_addr("106.38.211.3"); /// addr.sin_family = AF_INET;addr.sin_port = htons(80);if (SOCKET_ERROR == connect(sockeId, (SOCKADDR * )&addr, sizeof(addr))){printf("连接服务器失败");closesocket(sockeId);WSACleanup();return ;}// 初始化请求的数据char* pReqHead = new char[BuffSize];pReqHead[0] = '\0';// 请求行strcat(pReqHead,"GET ");strcat(pReqHead,"/download/AppStore/0831c047a8a8e4cff181d1466c39f5d4145402b80/com.julanling.app.apk");strcat(pReqHead," HTTP/1.1\r\n");//headersstrcat(pReqHead,"host:");strcat(pReqHead,"f1.market.xiaomi.com");strcat(pReqHead, "\r\nConnection: Close\r\n\r\n");printf(pReqHead);if (SOCKET_ERROR == send(sockeId, pReqHead, strlen(pReqHead), 0)){printf("发送数据失败");closesocket(sockeId);WSACleanup();delete pReqHead;return ;}delete pReqHead;FILE *fp,*fRes;fp = fopen("f:/down.apk", "wb+");fRes = fopen("f:/down.txt","wb+");if (NULL == fp){printf("创建文件失败");closesocket(sockeId);WSACleanup();return ;}char* buff = (char*)malloc(BuffSize*sizeof(char));memset(buff,'\0',BuffSize);int iRec = 0;bool bStart = false;while ((iRec =recv(sockeId, buff, BuffSize, 0)) > 0){if(bStart){fwrite(buff,iRec,1,fp);}else{char* pEnd = strstr(buff,"\r\n\r\n");if(pEnd==NULL){fwrite(buff,iRec,1,fp);fwrite(buff,iRec,1,fRes);}else{bStart = true;int iHead = pEnd+4-buff;fwrite(pEnd+4,iRec-(iHead),1,fp);fwrite(buff,iHead,1,fRes);}}     }fclose(fp);fclose(fRes);free(buff);closesocket(sockeId);WSACleanup();printf("下载结束");
}int main(){downLoad();return 1;
}

收到服务器返回的数据后,我们就去找\r\n\r\n,这是部首结束的地方,也就是资源文件开始的地方,

由于我们发起请求时,connection的值是close,所以,服务器发送完资源文件后就会断开连接,因此,

我们不需要检查文件的长度,当iRec 等于0时,就表明数据接收结束了。在下载文件的同时,

我也把服务器的响应头信息记录了下来。

HTTP/1.1 200 OK
Server: ATS/4.0.2
Content-Type: application/vnd.android.package-archive
Content-Length: 5617051
Last-Modified: Sun, 16 Aug 2015 08:19:41 GMT
X-Down-Hit: lg-miui-file-mfs09.bj
Expires: Mon, 14 Sep 2015 03:58:02 GMT
Cache-Control: max-age=2419200
Date: Mon, 24 Aug 2015 01:19:49 GMT
Connection: close
Via: http/1.1 miCDN (ApacheTrafficServer/4.0.2 [cHs f ])

应该说,上面的程序非常简单,我们没有考虑connection : keep-alive的情况,也没有考虑分块编码的情况,

如果是长连接,或者是分块编码,那么我们的程序是需要作出相应的调整的。

下一篇博文将介绍http响应头和响应部首。

http协议请求部首详解以及用c++写socket下载文件相关推荐

  1. linux上传文件put,详解Linux ftp 命令行中下载文件get与上传文件put的操作方法

    尽管现在有许多好的FTP应用程序,但服务器命令行ftp命令的应用程序仍然很多,下面就让电脑乐园小编带你一起来学习详解Linux ftp 命令行中下载文件get与上传文件put的操作方法. 介绍:从本地 ...

  2. 通过CURL请求示例详解HTTPS协议

    通过CURL请求示例详解HTTPS协议 基于HTTPS通信是当前互联网最通用便捷的通信方式,简单理解来看可以视为HTTP协议 + SSL/TLS协议,通过一个curl的示例阐述一下HTTPS协议. 特 ...

  3. HTTP协议状态码详解(HTTP Status Code)

    HTTP协议状态码详解(HTTP Status Code) 使用ASP.NET/PHP/JSP 或者javascript都会用到http的不同状态,一些常见的状态码为: 200 – 服务器成功返回网页 ...

  4. SSL / TLS 协议运行机制详解

    转载自  SSL / TLS 协议运行机制详解 互联网的通信安全,建立在SSL/TLS协议之上. 本文简要介绍SSL/TLS协议的运行机制.文章的重点是设计思想和运行过程,不涉及具体的实现细节.如果想 ...

  5. HTTP协议状态码详解(HTTP Status Code)(转)

    原文链接:HTTP协议状态码详解(HTTP Status Code) 使用ASP.NET/PHP/JSP 或者javascript都会用到http的不同状态,一些常见的状态码为:  200 – 服务器 ...

  6. TCP/IP协议分层模型详解

    文章目录 不同分类模型对应关系 不同人员关注的模型不一样 每层的简述 物理层 数据链路层 网络层 传输层 会话层 表示层 应用层 数据包传输过程 数据包传输调用关系 数据包发送 数据包接收 各层协议 ...

  7. 流媒体协议之RTMP详解

    流媒体协议之RTMP详解 文章目录 流媒体协议之RTMP详解 1 RTMP概述 2 RTMP交互过程 2.1 握手协议 2.2 RTMP分块(chunk) 2.3 协议控制消息(Protocol Co ...

  8. Telnet协议详解及使用C# 用Socket 编程来实现Telnet协议 - Atpking - 博客园

    Telnet协议详解及使用C# 用Socket 编程来实现Telnet协议 - Atpking - 博客园 Telnet协议详解及使用C# 用Socket 编程来实现Telnet协议 - Atpkin ...

  9. 流媒体协议之RTSP详解

    1 流媒体协议之RTSP详解 文章目录 1 流媒体协议之RTSP详解 1.1 RTSP概述 1.2 RTSP协议交互过程 1.2.1 RTSP基于TCP交互过程 1.2.2 RTSP基于HTTP的交互 ...

最新文章

  1. 【python】一个目录里面多个python程序文件,统计一下里面有多少行代码。即分别列出:代码、空行、注释的行数。
  2. CV之FR:计算机视觉之人脸识别(Face Recognition)方向的简介、使用方法、案例应用之详细攻略
  3. 设计模式(4)--AbstractFactory(抽象工厂模式)--创建型
  4. 【POJ - 1789】【ZOJ - 2158】【SCU - 1832】Truck History (最小生成树)
  5. 深入解读:获Forrester大数据能力高评价的阿里云DataWorks思路与能力
  6. VSCode 如何新建vue模板 - 插件引入篇
  7. leetcood学习笔记-107-二叉树的层次遍历二
  8. slice_input_producer在2.0版本里怎么用_EPrime2.0安装避坑指南
  9. 统计学习方法——统计学习基础(一)
  10. oa人员导入模板_别拿OA不当系统,让CIO困惑的几个OA小问题
  11. 如何在Word文档中制作三线表
  12. 树的计数 + prufer序列与Cayley公式 学习笔记
  13. sklearn的系统学习——决策树分类器(含有python完整代码)
  14. linux命令界面切换桌面,Linux图形界面和命令行界面切换
  15. TCP/IP协议分层
  16. 有关vue转换时间为年月日格式
  17. op 分析 这个绝对值电路OP1是怎么工作的?
  18. 【linux kernel】基于ARM64分析linux内核的链接脚本vmlinux.lds.S
  19. linux系统查看系统配置
  20. 二叉树的顺序结构及实现

热门文章

  1. 参考任哲的《嵌入式实时操作系统μC_OS-II原理及应用》,对UCOS的任务调度做了下整理。
  2. 【实训知识点记录】2.1插播结课作业需要的技术栈介绍
  3. 服务器升级debian9_如何在Debian 9上设置PageKite前端服务器
  4. ## 区块链手机—“恋战”,将要入局
  5. linux下.xz文件的解压方式
  6. B3402 [Usaco2009 Open]Hide and Seek 捉迷藏 最短路
  7. mysql 安顺寻_16名被拐宝贝到安顺寻亲 6个“贵州娃”与家人团圆
  8. JavaScript——练习题(2)
  9. 【附源码】Java计算机毕业设计安卓英语答题APP(程序+LW+部署)
  10. ICMP协议(最常用的ping、tracert命令)