#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <fstream>
#include <vector>
#include <pthread.h>
using namespace std;
typedef string::size_type (string::*find_t)(const string& delim,
string::size_type offset) const;
vector<string> Split(const string& s,
const string& match,
bool removeEmpty=false,
bool fullMatch=false)
{
vector<string> result; // return container for tokens
string::size_type start = , // starting position for searches
skip = ; // positions to skip after a match
find_t pfind = &string::find_first_of; // search algorithm for matches
if (fullMatch)
{
skip = match.length();
pfind = &string::find;
}
while (start != string::npos)
{
string::size_type end = (s.*pfind)(match, start);
if (skip == ) end = string::npos;
string token = s.substr(start, end - start);
if (!(removeEmpty && token.empty()))
{
result.push_back(token);
}
if ((start = end) != string::npos) start += skip;
}
return result;
}
void SplitProperty(vector<string> property,string* name,string *value)
{
vector<string>::iterator it=property.begin();
if(it!= property.end())
{
name->clear();
name->append(*it);
}
it++;
if(it!= property.end())
{
value->clear();
value->append(*it);
}
}
int GetFileSize(char* host,char* file,string* error,int& headersize)
{
int size=-;
struct sockaddr_in servaddr;
struct hostent *hp;
string splitline="\r\n";
string PName;
string PValue;
string splittagbalue=":";
string info;
vector<string> properties;
vector<string> property;
int sock_id;
char message[*] = {};
int msglen;
string request;
request.append("HEAD ");
request.append(file);
request.append(" HTTP/1.1\n");
request.append("Host:");
request.append(host);
request.append("\r\n\r\n");
//Get a socket
if((sock_id = socket(AF_INET, SOCK_STREAM, )) == -) {
error->append("Couldn't get a socket!");
return size;
}
//book uses bzero which my man pages say is deprecated
//the man page said to use memset instead. :-)
memset(&servaddr,,sizeof(servaddr));
//get address for google.com
if((hp = gethostbyname(host)) == NULL) {
error->append("Couldn't access network.");
error->append(host);
return size;
}
//bcopy is deprecated also, using memcpy instead
memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
//fill int port number and type
servaddr.sin_port = htons();
servaddr.sin_family = AF_INET;
//make the connection
if(connect(sock_id, (struct sockaddr *)&servaddr, sizeof(servaddr)) != ) {
error->append("Couldn't connect!");
return size;
}
write(sock_id,request.c_str(),request.length());
//read the response
msglen = read(sock_id,message,*);
headersize= msglen;
info.append(message,,msglen);
close(sock_id);
properties =Split(info,splitline,true);
vector<string>::iterator it;
for (it=properties.begin(); it<properties.end(); it++)
{
property= Split(*it,splittagbalue,true);
SplitProperty(property,&PName,&PValue);
if(PName=="Content-Length")
{
size =atoi(PValue.c_str());
break;
}
}
if(size==-)
{
error->append("Resource Not Found!");
}
return size;
}
void DownloadFile(char* host,char* file,char * savefile,float size,int& progress,int hsize)
{
struct sockaddr_in servaddr;
struct hostent *hp;
string info;
int sock_id;
char message[] = {};
char messagetop[]={};
int msglen;
float readcount=;
string request;
request.append("GET ");
request.append(file);
request.append(" HTTP/1.1\n");
request.append("Host:");
request.append(host);
request.append("\r\n\r\n");
//Get a socket
if((sock_id = socket(AF_INET, SOCK_STREAM, )) == -) {
return;
}
//book uses bzero which my man pages say is deprecated
//the man page said to use memset instead. :-)
memset(&servaddr,,sizeof(servaddr));
//get address for google.com
if((hp = gethostbyname(host)) == NULL) {
return;
}
//bcopy is deprecated also, using memcpy instead
memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
//fill int port number and type
servaddr.sin_port = htons();
servaddr.sin_family = AF_INET;
//make the connection
if(connect(sock_id, (struct sockaddr *)&servaddr, sizeof(servaddr)) != ) {
return;
}
//NOW THE HTTP PART!!!
//send the request
write(sock_id,request.c_str(),request.length());
ofstream outfile (savefile,ofstream::binary);
do{
msglen = read(sock_id,message,);
if(msglen==)
break;
if(readcount==)
{
int tempindex=;
for(int i =hsize-;i<msglen;i++)
{
messagetop[tempindex]= message[i];
tempindex=tempindex+;
}
outfile.write (messagetop,tempindex);
}
else
{
outfile.write (message,msglen);
}
readcount=readcount+msglen;
progress=readcount/size*;
}while(readcount<=(size+ hsize));
outfile.close();
close(sock_id);
//read the response
}
float filesize;
int loadprogress=;
int hsize;
pthread_t tUpdateWork;
void* UpdateWorCoping(void* data)
{
DownloadFile("192.168.2.128","/games.data","/usr/games.data",filesize,loadprogress,hsize);
}
int main(int argc, char** argv)
{
string error;
filesize = GetFileSize("192.168.2.128","/games.data",&error,hsize);
pthread_create(&tUpdateWork,NULL,UpdateWorCoping,);
while(loadprogress<)
{
printf("Progress %d \n", loadprogress);
usleep();
}
return ;
}

在使用该代码测试的时候可能会出现的问题:

1.

在DownloadFile 内的有两处:

 char message[18000] = {0};
 char messagetop[18000]={0};
可能在运行的时候造成栈溢出,所以最好是修改为动态申请空间。
另外还有一处就是GetFileSize() 内 问题同上。

2.

在DownloadFile() 内的写文件中:

里面有个for循环:for(int i = hsize -1; i<msglen ; i++)

我在亲自测试的发现 hsize - 1 会使文件保存大小跟原始文件有出入。于是暂时改成了 for(int i = hsize ; i<msglen ; i++)

不知道对于其他类型文件是否应该 做 -1 操作。待以后再测一测看看。

linux c++下载http文件并显示进度<转>的更多相关文章

  1. 实现在 .net 中使用 HttpClient 下载文件时显示进度

    在 .net framework 中,要实现下载文件并显示进度的话,最简单的做法是使用 WebClient 类.订阅 DownloadProgressChanged 事件就行了. 但是很可惜,WebC ...

  2. 使用libcurl开源库和Duilib做的下载文件并显示进度条的小工具

    转载:http://blog.csdn.net/mfcing/article/details/43603525 转载:http://blog.csdn.net/infoworld/article/de ...

  3. C# WinFrom 导入Excel文件,显示进度条

    因为WINForm程序是在64位上运行如果使用另外一种快速的读取Excel的方法会报“未在本地计算机上注册“Microsoft.Jet.OLEDB.12.0”提供程序” 所以我就换了现在这种读取有点慢 ...

  4. 从Linux服务器下载网站文件

    最近公司迁来一个新客户,该客户的网站是别的网络服务商做的,放在linux主机上,因为客户跟之前的网络服务商合作的不愉快 所以就把网站迁到我们公司,经理让我把网站文件和数据库download下来并在我们 ...

  5. C# Winform下载文件并显示进度条

    private void btnDown_Click(object sender, EventArgs e) { DownloadFile("http://localhost:1928/We ...

  6. Winform下载文件并显示进度条

    本来是要研究怎样判断下载完成,结果找到这个方法,可以在这个方法完成之后提示下载完成. 代码如下: using System; using System.Collections.Generic; usi ...

  7. 通过HttpUrlConnection下载文件并显示进度条

    实现效果: 核心下载块: int count = 0; URL url = new URL("http://hezuo.downxunlei.com/xunlei_hezuo/thunder ...

  8. [c#]WebClient异步下载文件并显示进度

    摘要 在项目开发中经常会用到下载文件,这里使用winform实现了一个带进度条的例子. 一个例子 using System; using System.Collections.Generic; usi ...

  9. ajax 上传文件,显示进度条,进度条100%,进度条隐藏,出现卡顿就隐藏进度条,显示正在加载,再显示上传完成

    <form id="uploadForm" method="post" enctype="multipart/form-data"&g ...

随机推荐

  1. 二叉搜索树的第k大的节点

    题目 给定一颗二叉搜索树,请找出其中的第k大的结点. 思路 如果中序遍历一棵二叉搜索树,遍历序列的数值则是递增排序,因此只需中序遍历一个二叉搜索树即可. #include <iostream&g ...

  2. FastAdmin 开发环境详细设置

    一图胜千言 FastAdmin开发环境 Windows 网页安装 鼠标点点就可以了,不用说明. 命令行安装 环境准备 装有 Windows 7 的PC .(这是一句废话,不用理这句.) 服务器软件 A ...

  3. [Python] 中文路径和中文文本文件乱码问题

    情景: Python首先读取名为log.txt的文本文件, 其中包含有文件名相对路径信息filename. 随后Python调用shutil.copy2(src, dst)对该filename文件进行 ...

  4. 【转】每天一个linux命令(44):top命令

    原文网址:http://www.cnblogs.com/peida/archive/2012/12/24/2831353.html top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进 ...

  5. oracle之 redo过高诊断

    一.诊断过度redo 要找到生成大量重做的会话,您可以使用以下任何一种方法.这两种方法都检查生成的撤销量.当一个事务生成撤销,它将自动生成重做. 当需要检查生成大量的程序时,使用第一个查询.当这些程序 ...

  6. GPU驱动兼容性问题

    GPU驱动兼容性问题 问题描述: 将笔记本的GTX860M 的驱动升级到了376.09版本,出现登陆界面,输入密码后黑屏. 解决思路: 由于正常显示登陆窗口,且可以输入密码,基本排除硬件问题和集成显卡 ...

  7. msp430学习笔记-IO及低功耗

    引用:http://bbs.ednchina.com/BLOG_ARTICLE_3013511.HTM MSP430F149有6个8位的IO口,其中P1,P2口占两个中断向量,共可以接16个中断源.还 ...

  8. WCF揭秘学习笔记(4):可信赖会话、会话管理、队列、事务

    可信赖会话 WCF的可信赖会话在绑定层保证消息只会被传输一次,并且保证消息间的顺序.当使用TCP通信时,协议本身保证了可靠性,但它只在两点间的网络 包这个层面提供了这样的保证.WCF的可信赖会话特性保 ...

  9. WPF Demo9外部资源文件

    <Window x:Class="Demos.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/ ...

  10. Java技术专题之JVM你的内存泄露了吗?

    一.从一个例子开始 关于JVM的内存泄露,让我们从下面一个例子开始吧,大家来判断一下如果按照下面这种分配方式,会不会出现内存泄露呢? import java.util.List; import jav ...