分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

使用libcurl下载文件小例

发布时间:2023-09-06 01:15责任编辑:熊小新关键词:url

libcurl是一个很强大的开源网络处理库,支持包括HTTP、HTTPS、FTP……一系列网络协议。用它来进行HTTP的get\post 或者下载文件更是小菜一碟,chrome内核都用到了它,本文主要讲解一个使用curl下载文件的小例。

首先是去下载curl的最新源代码,然后编译成动态库或者静态库;然后把头文件和库文件拿出来加入到我们自己的工程中,引用声明:

#include "curl.h" ?#ifdef _DEBUG ?#pragma comment(lib, "../Debug/libcurld") ?#else ?#pragma comment(lib, "../Release/libcurl") ?#endif ?

特意在原有代码上加了一些注释,希望可以更好理解,上代码:

<pre name="code" class="cpp">// UseLibCurl.cpp : 定义控制台应用程序的入口点。 ?// ???#include "stdafx.h" ?#include <Windows.h> ?#include <CommCtrl.h> ?#include "resource.h" ?#include "curl.h" ?#ifdef _DEBUG ?#pragma comment(lib, "../Debug/libcurld") ?#else ?#pragma comment(lib, "../Release/libcurl") ?#endif ?????//这个用来保存对话框的窗口句柄,因为后面要向这个窗口发消息,必须知道其窗口句柄 ?HWND ???g_hDlgWnd = NULL; ?//提供给CURL下载进度回调的函数,用于保存下载的数据到文件 ?static size_t ??DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam); ?//提供给CURL下载进度回调的函数,用于计算下载进度通知界面 ?static int ProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); ?//这是对话框的消息循环,在控制台程序里面创建GUI,仅仅是为了更好地展现下载回调这个功能 ?INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); ?//这个是下载的线程函数,为了不把对话框主界面卡死,肯定是要自己开线程来下载的了 ?DWORD WINAPI DownloadThread(LPVOID lpParam); ???int _tmain(int argc, _TCHAR* argv[]) ?{ ?????//弹出对话框,知道对话框关闭才会执行退出 ?????DialogBox(NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc ); ?????return 0; ?} ???static size_t DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam) ?{ ?????//把下载到的数据以追加的方式写入文件(一定要有a,否则前面写入的内容就会被覆盖了) ?????FILE* fp = NULL; ?????fopen_s(&fp, "c:\\test.apk", "ab+"); ?????size_t nWrite = fwrite(pBuffer, nSize, nMemByte, fp); ?????fclose(fp); ?????return nWrite; ?} ???static int ProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) ?{ ?????if ( dltotal > -0.1 && dltotal < 0.1 ) ?????????return 0; ?????int nPos = (int) ( (dlnow/dltotal)*100 ); ?????//通知进度条更新下载进度 ?????::PostMessage(g_hDlgWnd, WM_USER + 110, nPos, 0); ?????//::Sleep(10); ?????return 0; ?} ???INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ?{ ?????switch( uMsg ) ?????{ ?????case WM_INITDIALOG: ?????????{ ?????????????g_hDlgWnd = hWnd; ?????????????HWND hProgress = GetDlgItem(hWnd, IDC_PROGRESS1); ?????????????SendMessage(hProgress, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) 100); ?????????????//对话框初始化时创建下载线程 ?????????????HANDLE hThread = CreateThread(NULL, 0, DownloadThread, 0, 0, NULL); ?????????????CloseHandle(hThread); ?????????????::SetWindowText(hWnd, L"使用CURL下载文件示例:"); ?????????????return TRUE; ?????????} ?????case WM_COMMAND: ?????????{ ?????????????WORD ?msg = HIWORD(wParam); ?????????????WORD ?id ?= LOWORD(wParam); ?????????????if ( id == IDOK || id == IDCANCEL ) ?????????????????EndDialog(hWnd, id); ?????????????break; ?????????} ?????case WM_ERASEBKGND: ?????????return TRUE; ?????case WM_CTLCOLORSTATIC: ?????????return (INT_PTR)(HBRUSH)::GetStockObject(WHITE_BRUSH); ?????case WM_USER + 110: ?????????{//接收到设置进度的消息 ?????????????HWND ???hProgress ??= GetDlgItem(hWnd, IDC_PROGRESS1); ?????????????HWND ???hStatus ????= GetDlgItem(hWnd, IDC_STATUS); ?????????????if ( hProgress ) ?????????????????SendMessage(hProgress, PBM_SETPOS, wParam, 0L); ?????????????if ( hStatus ) ?????????????{ ?????????????????WCHAR szBuffer[100] = {0}; ?????????????????if ( wParam<100 ) ?????????????????????swprintf(szBuffer, L"正在下载文件,进度:%d%%", wParam); ?????????????????else ?????????????????????swprintf(szBuffer, L"文件下载完毕!"); ?????????????????::SetWindowText(hStatus, szBuffer); ?????????????} ?????????????return 0; ?????????} ?????default: ?????????break; ?????} ?????return DefWindowProc(hWnd, uMsg, wParam, lParam); ?} ???DWORD WINAPI DownloadThread(LPVOID lpParam) ?{ ?????//初始化curl,这个是必须的 ?????CURL* curl = curl_easy_init(); ?????curl_easy_setopt(curl, CURLOPT_URL, "http://android.shoujids.com/software/download?id=154103"); ?????//设置接收数据的回调 ?????curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DownloadCallback); ?????//curl_easy_setopt(curl, CURLOPT_INFILESIZE, lFileSize); ?????//curl_easy_setopt(curl, CURLOPT_HEADER, 1); ?????//curl_easy_setopt(curl, CURLOPT_NOBODY, 1); ?????//curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); ?????// 设置重定向的最大次数 ?????curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5); ?????// 设置301、302跳转跟随location ?????curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); ?????curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); ?????//设置进度回调函数 ?????curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, ProgressCallback); ?????//curl_easy_getinfo(curl, ?CURLINFO_CONTENT_LENGTH_DOWNLOAD, &lFileSize); ?????//curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, g_hDlgWnd); ?????//开始执行请求 ?????CURLcode retcCode = curl_easy_perform(curl); ?????//查看是否有出错信息 ?????const char* pError = curl_easy_strerror(retcCode); ?????//清理curl,和前面的初始化匹配 ?????curl_easy_cleanup(curl); ?????return 0; ?} ?

原文链接:使用libcurl下载文件小例

使用libcurl下载文件小例

原文地址:http://www.cnblogs.com/rainbow70626/p/7618378.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved