1 背景知识
2 libcurl 基础知识
3 libcurl两种模式
4 libcurl实例分析
1 背景知识:
1.1 基本网络通信cs模式,select 框架,网上例子很多.下面只介绍epoll的难点.其他内容请自行搜索.
1.2 epoll 用法
1.2.1 基础知识:
在自己端准备write之前,通过epoll ctrl设置成epoll out.
epoll in 是被动监听接收,epoll out是主动设置.
1.2.2 epoll 模型:网上例子很多.
这个是最简单异步,先发送--等待--接收,这种用法很少用了
https://blog.csdn.net/lijinqi1987/article/details/53925835 and https://blog.csdn.net/Rong_Toa/article/details/105712677 .
本文讨论curl_multi_socket_action 方案.
**3.1 easy 模式(这种模式比较简单) **
调用curl_easy_setopt函数设置传输的一些基本参数,CULROPT_URL必填.设置完成后,调用curl_easy_perform函数发送数据.
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_WRITEDATA, void *pointer)
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url)
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb)
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn)
第一句 curl建立与url 连接,第二句将respond 发送到write_cb,第三句是将write_cb处理内容写入conn指向的文件
3.2 multi 模式
1 ) 常用函数介绍(注意参数)
a ) CURLMOPT_SOCKETFUNCTION:设置socket的回调函数.是所有socket 变化都会调用callback(不仅仅是socket connect,read/write也调用).
对于接收的话,CURLMOPT_SOCKETDATA没用。socketp是返回值。
CURLMOPT_TIMERDATA and CURLOPT_WRITEDATA 都是对应 curl function的入参.
b) CURLMOPT_TIMERFUNCTION :set callback to receive timeout values
You can also use the curl_multi_timeout function to poll the value at any given time,
but for an event-based system using the callback is far better than relying on polling the timeout value.
系统超时 *** 作触发callback.
c ) CURLOPT_WRITEFUNCTION:set callback for writing received data
CURLOPT_WRITEDATA:custom pointer passed to the write callback
设置CURLOPT_WRITEFUNCTION的参数4,把参数1 ptr指向的数据拷到参数4 userdata
d ) curl_multi_setopt
CURLMOPT_TIMERDATA:The userp pointer is set with CURLMOPT_TIMERDATA. 入参
curl_multi_setopt is used to tell a libcurl multi handle how to behave.
CURLMOPT_SOCKETFUNCTION,CURLMOPT_SOCKETDATA,CURLMOPT_TIMERFUNCTION,CURLMOPT_TIMERDATA
e) curl_multi_assign
set association sockfd with sockptr curl系统中将sockfd和sockpt结构体绑定
执行curl命令.curl_multi_socket_action=curl_multi_perform:reads/writes available data given an action.通知libcurl读写数据
执行curl_multi_add_handle中的东东. 注意参数3ev_bitmask是action.
比如: 设置了CURLMOPT_SOCKETFUNCTION就从server download file.设置CURLMOPT_UPLOAD就是上传file.
CURLOPT_WRITEFUNCTION 就调用CURLOPT_WRITEDATA将download data写入file.
curl同时和socket,epoll,file 同时打交道.
curl精华:curl_multi_socket_action可以自动get file from server(CURLOPT_URL) and 自动write file to local(CURLOPT_WRITEFUNCTION)
4.1 curl+ epoll
CURLOPT_URL=connect,CURLMOPT_SOCKETFUNCTION=epoll_ctrl, curl_multi_socket_action=get remote file and write file to local ,epoll=select.
实现步骤和时序:
https://curl.haxx.se/libcurl/c/ephiperfifo.html
[ https://www.jianshu.com/p/80274bc54aff]
( https://www.jianshu.com/p/80274bc54aff )
https://blog.csdn.net/Rong_Toa/article/details/105712677
https://blog.csdn.net/lijinqi1987/article/details/53996129
https://www.cnblogs.com/zl-graduate/articles/6724446.html
用libcurl实现下载功能很方便,只要调用libcurl库即可。long downloadFileLenth = 0
1
2
3
4
5
6
7
8
9
10
11
12
CURL *handle = curl_easy_init()
curl_easy_setopt(handle, CURLOPT_URL, url)
curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, “GET”) //使用CURLOPT_CUSTOMREQUEST
curl_easy_setopt(handle, CURLOPT_NOBODY, 1) //不需求body
if (curl_easy_perform(handle) == CURLE_OK)
{
curl_easy_getinfo(handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &downloadFileLenth)
}
else {
downloadFileLenth = -1
}
curl_easy_cleanup(handle)
可以完美解决用GET获取文件长度,而不下载文件内容。
#include <io.h>#include "curl/curl.h"
#pragma comment(lib, "ws2_32.lib")
#pragma comment ( lib, "libcurl.lib" )
#pragma comment ( lib, "ws2_32.lib" )
#pragma comment ( lib, "winmm.lib" )
#pragma comment ( lib, "wldap32.lib" )
//这是libcurl接收数据的回调函数,相当于recv的死循环
//其中stream可以自定义数据类型,这里我传入的是文件保存路径
static size_t write_callback( void *ptr, size_t size, size_t nmemb, void *stream )
{
int len = size * nmemb
int written = len
FILE *fp = NULL
if ( access( (char*)stream, 0 ) == -1 )
{
fp = fopen( (char*) stream, "wb" )
}
else
{
fp = fopen( (char*) stream, "ab" )
}
if (fp)
{
fwrite( ptr, size, nmemb, fp )
}
return written
}
int GetUrl( const char *url, char *savepath )
{
CURL *curl
CURLcode res
struct curl_slist *chunk = NULL
curl = curl_easy_init()
if ( curl ) {
curl_easy_setopt( curl, CURLOPT_VERBOSE, 0L )
curl_easy_setopt( curl, CURLOPT_URL, url )
//指定回调函数
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_callback)
//这个变量可作为接收或传递数据的作用
curl_easy_setopt( curl, CURLOPT_WRITEDATA, savepath )
res = curl_easy_perform( curl )
if (res == CURLE_OK)
{
return 1
}
return 0
}
}
int main( void )
{
if ( GetUrl( "t.sina.com.cn", "c:/1.txt" ) )
{
printf( "OK" )
}
return 0
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)