常用libcurl异步使用方法

常用libcurl异步使用方法,第1张

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

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11552850.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存