#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. 【python下使用OpenCV实现计算机视觉读书笔记3】读写视频文件

    代码例如以下: import cv2 videoCapture = cv2.VideoCapture('car.avi') fps = videoCapture.get(cv2.cv.CV_CAP_P ...

  2. 网络基础 TCP/IP

    为了理解 HTTP,我们有必要事先了解一下 TCP/IP 协议族.通常使用的网络(包括互联网)是在 TCP/IP 协议族的基础上运作的.而 HTTP 属于它内部的一个子集.接下来,我们仅介绍理解 HT ...

  3. php 中的引用

    php 有类似 C 中的指针 &. 但在 php 中叫 引用. 虽然和 传地址很像,但是差别很大.(估计底层实现应该差不多,只是猜想,有机会再研究) 这里有一个关于 php 的对象的赋值其实就 ...

  4. [LeetCode系列] 双单链表共同节点搜索问题

    找到两个单链表的共同节点. 举例来说, 下面两个链表A和B: A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3 共同节点为c1. 分析: 共同节点距离A,B的起点 ...

  5. ASM 磁盘、目录的管理

    --======================== -- ASM 磁盘.目录的管理 --======================== ASM磁盘是ASM体系结构的重要组成部分,ASM磁盘由ASM ...

  6. JUC锁之 框架

    根据锁的添加到Java中的时间,Java中的锁,可以分为"同步锁"和"JUC包中的锁". 同步锁 即通过synchronized关键字来进行同步,实现对竞争资源 ...

  7. JVM内存模型(一)

    主要澄清之前对JVM内存模型的一些误区: JMV内存主要分为5块:方法区(Method Area),堆区(Heap),虚拟机栈(VM stack),本地方法栈(Native Method stack) ...

  8. 洛谷2530(codevs2098)化工厂装箱员

    题目:https://www.luogu.org/problemnew/show/P2530 dp或搜索. dp做法就是 当前值+1 转移到 当前某一维为0.位置前进了c位 的地方.但没写. 写了搜索 ...

  9. BASIC-29_蓝桥杯_高精度加法

    题目: 问题描述 输入两个整数a和b,输出这两个整数的和.a和b都不超过100位. 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储.对于这种问题,一般使用数组来处理. 定义一 ...

  10. appium+python自动化42-微信公众号

    前言 本篇介绍如何在微信公众号上自动化测试,以操作我的个人公众号:yoyoketang为例,没关注的,先微信关注了,再跟着操作 环境准备: python 3.6 appium 1.7以上版本 微信6. ...