通过发送HTTP请求,下载文件

头文件:

 #ifndef __HTTP__
#define __HTTP__ #include <stdio.h>
#include <stdlib.h>
#include <string>
#include <winsock.h> using namespace std; /**
* URL相关数据
*/
typedef struct _URLData {
string url; // 完整的url地址
string path; // 文件路径
string host; // 主机名
string ip; // 点分隔的ip
int port; // 端口
string resName; // 资源名字
} URLData; /**
* 解析url
*/
void parseURL(string url, URLData* data); /**
* 链接http服务器
*/
bool connectHttpServer(int socketId, string ip, int port); /**
* 生成请求文本
*/
void generateRequestTxt(URLData* data, string* requestTxt); /**
* 发送http请求
*/
bool sendHttpRequest(int socketId, string* requestTxt); /**
* 接受响应数据
*/
void recvHttpResponse(int socketId, string* responseTxt); /**
* 保存http数据
*/
bool saveHttpData(string* responseTxt, string filePath = "", string fileName = ""); /**
* 获取http资源
*/
bool getHttpResource(string url, string filePath = "", string fileName = ""); #endif

代码文件:

 #include "http.h"
#include "DNS/DNS.h"
#include "time.h" /**
* 解析url
*/
void parseURL(string url, URLData* data)
{
int startPos = ;
string begin = url.substr(, );
if (begin == "http") {
startPos = ;
} int i = startPos;
int lastSplitPos = ;
for (int len = url.length(); i<len; i++) {
unsigned char ch = url.at(i); if (ch == ) {
if (data->host.length() == ) {
data->host = url.substr(startPos, i - startPos);
data->path = url.substr(i, url.length() - i); break;
} lastSplitPos = i;
}
}
// data->path = url.substr(iPath, url.length() - iPath);
data->url = url;
data->port = ; int resNameLastPos = url.length()-;
int resNameFirstPos = ;
for (int i = url.length()-; i>=; i--) {
unsigned char ch = url.at(i); if (ch == '.')
resNameLastPos = i;
else if (ch == '/') {
resNameFirstPos = i + ;
break;
}
}
data->resName = url.substr(resNameFirstPos, resNameLastPos - resNameFirstPos);
} /**
* 链接HTTP服务器
*/
bool connectHttpServer(int socketId, string ip, int port)
{
// 初始套接字化地址
struct sockaddr_in serverAddr;
memset(&serverAddr, , sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.S_un.S_addr = inet_addr(ip.c_str());
serverAddr.sin_port = htons(port); if (connect(socketId, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
return false;
}
return true;
} /**
* 生成请求文本
*/
void generateRequestTxt(URLData* data, string* requestTxt)
{
requestTxt->append("GET "); requestTxt->append(data->path); requestTxt->append(" HTTP/1.1\r\n");
requestTxt->append("Host: "); requestTxt->append(data->host); requestTxt->append("\r\n");
requestTxt->append("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n");
requestTxt->append("Accept-Language: zh-CN,zh;q=0.8\r\n");
requestTxt->append("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36\r\n");
requestTxt->append("Accept-Encoding: deflate,sdch\r\n");
requestTxt->append("Connection: close\r\n\r\n");
} /**
* 发送http请求
*/
bool sendHttpRequest(int socketId, string* requestTxt)
{
int sendBytes = send(socketId, requestTxt->c_str(), requestTxt->length(), );
return sendBytes > ;
} /**
* 接受响应数据
*/
void recvHttpResponse(int socketId, string* responseTxt)
{
char buff[]; int recvBytes = ;
while ((recvBytes = recv(socketId, buff, , )) > ) {
responseTxt->append(buff, recvBytes);
}
} /**
* 保存http数据
*/
bool saveHttpData(string* responseTxt, string filePath, string fileName)
{
if (fileName == "") {
char _fileName[];
sprintf(_fileName, "%lld", time());
fileName = _fileName;
} string fileExt = "."; int i = , len = ;
for (i = , len = responseTxt->length(); i<len; i++) {
unsigned char ch = responseTxt->at(i); if (ch == 'C') {
unsigned char metaKey[], typeMetaKey[] = "Content-Type";
memset(metaKey, , );
memcpy(metaKey, responseTxt->c_str() + i, ); string metaValue;
if ( strcmp((char*)metaKey, (char*)typeMetaKey) == ) {
for (int j = i+;;j++) {
unsigned char ch = responseTxt->at(j); metaValue.push_back(ch);
if (ch == '\r') {
for (int k = , len = metaValue.length(); k<len; k++) {
if (metaValue.at(k) == '/') {
fileExt.append( metaValue.substr(k+, metaValue.length() - k - ) );
fileName.append(fileExt); break;
}
} break;
}
}
}
} if (ch == '\r' &&
responseTxt->at(i+) == '\n' &&
responseTxt->at(i+) == '\r' &&
responseTxt->at(i+) == '\n') {
i += ;
break;
}
} FILE* fp = fopen((filePath + fileName).c_str(), "wb+");
if (fp) {
fwrite(responseTxt->c_str() + i, , responseTxt->length() - i, fp);
fclose(fp); return true;
}
return false;
} /**
* 获取http资源
*/
bool getHttpResource(string url, string filePath, string fileName)
{
printf("-------------------------------------\n"); int socketId = socket(AF_INET, SOCK_STREAM, );
if (socketId == INVALID_SOCKET) {
printf("Create sokcet failed\n"); return false;
} // 解析url数据
URLData data;
parseURL(url, &data); // 获取DNS信息
if (!getIPAddrByDNS(data.host, &data.ip)) {
printf("Get ip(%s) from DNS server failed\n", data.host.c_str()); return false;
} // 生成请求文本
string requestTxt;
generateRequestTxt(&data, &requestTxt); // 链接服务器
if (!connectHttpServer(socketId, data.ip, data.port)) {
printf("Connect http server failed, ip:%s\n", data.ip.c_str()); return false;
} printf("Send http request:\n%s\n", requestTxt.c_str()); // 发送请求
if (!sendHttpRequest(socketId, &requestTxt)) {
printf("Send http request failed\n"); return false;
} // 接受响应
string responseTxt;
recvHttpResponse(socketId, &responseTxt); printf("Recive http response:\n%s\n", responseTxt.c_str()); // 保存数据
if (!saveHttpData(&responseTxt, filePath, (fileName.length() == ) ? data.resName : fileName)) {
printf("Save response data failed\n");
return false;
} closesocket(socketId); printf("-------------------------------------\n"); return true;
}

使用方法:

 string url = "http://static.youku.com/index/img/master.png";
getHttpResource(url);

使用HTTP协下载文件的更多相关文章

  1. Java远程下载文件到本地(http协议和ssh2协议)

    Java中java.io包为我们提供了输入流和输出流,对文件的读写基本上都依赖于这些封装好的关于流的类中来实现.前段时间遇到了以下两种需求: 1.与某系统对接,每天获取最新的图片并显示在前端页面.该系 ...

  2. [转]python3之paramiko模块(基于ssh连接进行远程登录服务器执行命令和上传下载文件的功能)

    转自:https://www.cnblogs.com/zhangxinqi/p/8372774.html 阅读目录 1.paramiko模块介绍 2.paramiko的使用方法 回到顶部 1.para ...

  3. Java下载文件(流的形式)

    @RequestMapping("download") @ResponseBody public void download(HttpServletResponse respons ...

  4. 使用批处理文件在FTP服务器 上传下载文件

    1.从ftp服务器根目录文件夹下的文件到指定的文件夹下 格式:ftp -s:[配置文件] [ftp地址] 如:ftp -s:c:\vc\ftpconfig.txt   192.168.1.1 建立一个 ...

  5. 通过form表单的形式下载文件。

    在项目中遇到问题,要求动态拼接uri下载文件.但是由于项目的安全拦截导致window.location.href 和 window.open等新建窗口的方法都不行. 无意间百度到了通过form表单来下 ...

  6. SecureCRT上传和下载文件

    SecureCRT上传和下载文件(下载默认目录) SecureCR 下的文件传输协议有ASCII .Xmodem .Ymodem .Zmodem ASCII:这是最快的传输协议,但只能传送文本文件. ...

  7. HTTP 错误 404.3 – Not Found 由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。

    今天,在vs2013中新建了一个placard.json文件,当我用jq读取它的时候,去提示404,直接在浏览器访问这个文件,提示: HTTP 错误 404.3 – Not Found 由于扩展配置问 ...

  8. FTP下载文件失败

    这几天的定时任务下载文件的脚本失败了. 于是手工执行测试,发现报550 Permission denied. Passive mode refused. 意思就是被动模式下,没有权限获取文件. 解决方 ...

  9. 如何使用FileZilla上传和下载文件

    一.使用FileZilla上传文件 1 打开 FileZilla 按照如下图所示,填写远程 Linux 的 IP ,用户名,密码,还有端口号(默认22) 2 选中左边需要上传的文件,然后拖到右边,等待 ...

随机推荐

  1. 五大Android布局方式浅析

    Android布局是应用界面开发的重要一环,在Android中,共有五种布局方式,分别是:FrameLayout(框架布局),LinearLayout (线性布局),AbsoluteLayout(绝对 ...

  2. Python 模块学习:re模块

    今天学习了Python中有关正则表达式的知识.关于正则表达式的语法,不作过多解释,网上有许多学习的资料.这里主要介绍Python中常用的正则表达式处理函数. 方法/属性 作用 match() 决定 R ...

  3. 2016 Multi-University Training Contest 5 World is Exploding

    转载自:http://blog.csdn.net/queuelovestack/article/details/52096337 [题意]给你一个序列A,选出四个下标不同的元素,下标记为a,b,c,d ...

  4. poj 1251 统计难题(字典树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251 AC代码: #include<iostream> #include<algor ...

  5. Ubuntu打开终端和设置root密码(转载)

    From:http://blog.csdn.net/xhhjin/article/details/6328752 http://www.linuxsir.org/bbs/thread318516.ht ...

  6. Yii2.0 实现三级联动 [ 2.0 版本 ]

    view中代码 <?php use yii\bootstrap\ActiveForm; /* @var $this yii\web\View */ /* @var $form yii\boots ...

  7. Linux下SVN服务器安装配置及客户端安装说明

    原文地址:http://wenku.baidu.com/link?url=h3dVAMx4azpOXEND5HQEE6nliE8-zc0GSQ03yv4cUs1vXMALXF64UsK7kT7kXm_ ...

  8. 客户端获取服务端自定义类数据 z

    客户端获取服务端自定义类数据 问题一:超时问题,在最后获取数据的时候突然提示服务超时,服务已断开 解决:配置文件添加: <bindings> <wsHttpBinding> & ...

  9. java 、android 知识图谱

    java知识图谱: android知识图谱: 照此图练习,神功自成.....

  10. Maven pom.xml 配置详解

    http://niuzhenxin.iteye.com/blog/2042102 http://blog.csdn.net/u012562943/article/details/51690744 po ...