c使用curl进行http访问

一、引入libcurl库

1、第一种方式

brew install curl命令

2、第二种方式

下载ssl,地址:https://www.openssl.org/source/openssl-3.0.2.tar.gz

下载curl,地址: https://curl.se/download/curl-7.82.0.tar.gz

并使用cmake ,指定ssl地址并 make编译(同c连接redis笔记,拿到libcurl.a和curl.h文件)

cmake ../ -DOPENSSL_ROOT_DIR=/usr/local/ssl -DOPENSSL_LIBRARIES=/usr/local/ssl/lib

二、cMakeList.txt

cmake_minimum_required(VERSION 3.21)
project(testc C)

set(CMAKE_C_STANDARD 99)

#添加头文件目录  (相当于gcc中-l参数,也相当于环境变量中增加路径到cplus_include_path变量的作用)
#语法:include_directories("/opt/……/extern/include") (相当于export CPLUS_INCLUDE_PATH=CPLUS_INCLUDE_PATH:$MATLAB/extern/include)
include_directories("/usr/local/opt/curl/include/curl")

#需要链接的库文件目录 (相当于gcc命令中的-L选项作用,也相当于环境变量中增加LD_LIBRARY_PATH的路径的作用)
#语法:LINK_DIRECTORIES("/opt/……/bin") (相当于export LD_LIBRARY_PATH=LD_LIBRARY_PATH:$MATLAB/bin)
link_directories("/usr/local/opt/curl/lib")

#添加需要链接的库文件全路径(在add_executable之前,已过时,推荐target_link_libraries)
#语法:LINK_LIBRARIES("/opt/……/bin/liba.so") 或LINK_LIBRARIES("/opt/……/bin/liba.so" "/opt/……/bin/libb.so")
#link_libraries()


#引入另外的cmake文件
#include()

#打包成可执行文件
add_executable(testc main.c)
#打包成库文件
#add_library()

#----------------------------------

#设置要链接的库文件名称(以下集中写法都可以,需要写在add_executable后)
#语法:TARGET_LINK_LIBRARIES(myProject hello) 链接libhello.so库
#或TARGET_LINK_LIBRARIES(myProject libhello.a)
#或TARGET_LINK_LIBRARIES(myProject libhello.so)
#或TARGET_LINK_LIBRARIES(myProject -lhello)
target_link_libraries(testc libcurl.a)

#设置要链接的库文件的全路径名称
#target_link_directories()

#指定可执行文件需要包含的头文件的路径
#target_include_directories()

三、main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl.h>
#include <unistd.h>
int main() {
    printf("Hello, World!\n");

    //1、curl全局初始化,初始化libcurl库(只能调用一次)
    //CURL_GLOBAL_ALL尽可能初始化一切(除了CURL_GLOBAL_ACK_EINTR)
    //CURL_GLOBAL_WIN32表示libcurl会初始化winsock库,如果失败则无法使用socket,windows系统专用
    //CURL_GLOBAL_SSL初始化SSL,(不初始化可能无法使用https)
    //CURL_GLOBAL_DEFAULT初始WIN32和SSL
    //CURL_GLOBAL_ACK_EINTR设置此标志后,curl将在连接或等待数据时确认EINTR条件。否则,curl会等待直到完全超时。(在7.30.0中添加)
    CURLcode init = curl_global_init(CURL_GLOBAL_ALL);
    if(init!=CURLE_OK){
        printf("curl全局初始化失败!\n");
        exit(1);
    }

    //2、初始化curl,返回CURL句柄
    CURL *curl = (struct CURL *)curl_easy_init();
    if(curl==NULL){
        printf("初始化CURL失败!\n");
        exit(1);
    }

    //3、设置option,各种curl参数的
    curl_easy_setopt(curl,CURLOPT_URL,"https://www.baidu.com/home/xman/data/tipspluslist");

    //设置保存位置,使用临时文件或保存到fopen中
    //FILE *file=fopen("1.txt","w");
    FILE *file=tmpfile();
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
    //各option
//    1.CURLOPT_URL
//    设置访问URL
//    2.CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA
//    通过设定一个回调函数,执行libcurl在接受到数据后用户想进行的操作,通常函数多做数据保存的功能,如处理下载文件。CURLOPT_WRITEDATA 用于表明CURLOPT_WRITEFUNCTION函数中的stream指针的来源,说白了就是设定回调函数的第四个参数的数据类型。回调函数原型为:size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
//    3.CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA
//    通过设定一个回调函数,执行libcurl在接受到http头数据后用户想进行的操作。CURLOPT_WRITEDATA 传递指针给libcurl,该指针表明CURLOPT_HEADERFUNCTION 函数的stream指针的来源。回调函数原型为 size_t function( void *ptr, size_t size,size_t nmemb, void *stream);
//    4.CURLOPT_READFUNCTION CURLOPT_READDATA
//    libCurl需要读取数据传递给远程主机时将调用CURLOPT_READFUNCTION指定的函数,函数原型是:size_t function(void *ptr, size_t size, size_t nmemb,void *stream). CURLOPT_READDATA 表明CURLOPT_READFUNCTION函数原型中的stream指针来源,说白了就是设定回调函数的第四个参数的数据类型。
//    5.CURLOPT_NOPROGRESS,CURLOPT_PROGRESSFUNCTION,CURLOPT_PROGRESSDATA
//    跟数据传输进度相关的参数。CURLOPT_PROGRESSFUNCTION 指定的函数正常情况下每秒被libcurl调用一次,为了使CURLOPT_PROGRESSFUNCTION被调 用,CURLOPT_NOPROGRESS必须被设置为false,CURLOPT_PROGRESSDATA指定的参数将作为 CURLOPT_PROGRESSFUNCTION指定函数的第一个参数
//    6.CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOUT:
//    CURLOPT_TIMEOUT 用于设置传输时间,CURLOPT_CONNECTIONTIMEOUT 设置连接等待时间
//    7.CURLOPT_FOLLOWLOCATION
//    设置重定位URL
//    CURLOPT_RANGE: CURLOPT_RESUME_FROM:
//    断点续传相关设置。CURLOPT_RANGE 指定char *参数传递给libcurl,用于指明http域的RANGE头域,例如:
//    表示头500个字节:bytes=0-499
//    表示第二个500字节:bytes=500-999
//    表示最后500个字节:bytes=-500
//    表示500字节以后的范围:bytes=500-
//                       第一个和最后一个字节:bytes=0-0,-1
//    同时指定几个范围:bytes=500-600,601-999
//    CURLOPT_RESUME_FROM 传递一个long参数给libcurl,指定你希望开始传递的偏移量。
//    8.CURLOPT_UPLOAD:
//    如果第三个参数被设置为1的话,就是让libcurl做好上传的准备。如果传输协议是http的话,uoload就是发送put。
//    9. CURLOPT_SSL_VERIFYPEER:
//    第三个参数的缺省值为1.该函数多用于设定curl忽略对网站证书的检查(不管忽略不忽略,curl都是检查的)。
//    10.CURLOPT_VERBOSE
//    相当厉害的一个参数,可以向控制台(默认)输出curl接受和发送的数据,输出流可以重定向。
//    11.CURLOPT_HTTPGET
//    将curl向服务器交互数据的方式改变为get

    //4、执行curl的各种操作的请求
    CURLcode curLcode = curl_easy_perform(curl);
    if(curLcode!=CURLE_OK){
        printf("curl请求失败:%s!\n",curLcode);
        exit(1);
    }
//    perform错误码说明:
//    1.CURLE_OK
//    任务完成一切都好
//    2.CURLE_UNSUPPORTED_PROTOCOL
//    不支持的协议,由URL的头部指定
//    3.CURLE_COULDNT_CONNECT
//    不能连接到remote 主机或者代理
//    4.CURLE_REMOTE_ACCESS_DENIED
//    访问被拒绝
//    5.CURLE_HTTP_RETURNED_ERROR
//    Http返回错误
//    6.CURLE_READ_ERROR
//    读本地文件错误

    //5、读取请求响应的信息
    int totalTime;
    curLcode=curl_easy_getinfo(curl,CURLINFO_TOTAL_TIME,&totalTime);
    if(curLcode!=CURLE_OK){
        printf("curl获取信息失败:%s!\n",curLcode);
    }
    printf("CURLINFO_TOTAL_TIME:%d!\n",totalTime);
//    getinfo参数
//    CURLINFO_EFFECTIVE_URL - 最后一个有效的URL地址
//    CURLINFO_HTTP_CODE - 最后一个收到的HTTP代码
//    CURLINFO_FILETIME - 远程获取文档的时间,如果无法获取,则返回值为“-1”
//    CURLINFO_TOTAL_TIME - 最后一次传输所消耗的时间
//    CURLINFO_NAMELOOKUP_TIME - 名称解析所消耗的时间
//    CURLINFO_CONNECT_TIME - 建立连接所消耗的时间
//    CURLINFO_PRETRANSFER_TIME - 从建立连接到准备传输所使用的时间
//    CURLINFO_STARTTRANSFER_TIME - 从建立连接到传输开始所使用的时间
//    CURLINFO_REDIRECT_TIME - 在事务传输开始前重定向所使用的时间
//    CURLINFO_SIZE_UPLOAD - 以字节为单位返回上传数据量的总值
//    CURLINFO_SIZE_DOWNLOAD - 以字节为单位返回下载数据量的总值
//    CURLINFO_SPEED_DOWNLOAD - 平均下载速度
//    CURLINFO_SPEED_UPLOAD - 平均上传速度
//    CURLINFO_HEADER_SIZE - header部分的大小
//    CURLINFO_HEADER_OUT - 发送请求的字符串
//    CURLINFO_REQUEST_SIZE - 在HTTP请求中有问题的请求的大小
//    CURLINFO_SSL_VERIFYRESULT - 通过设置CURLOPT_SSL_VERIFYPEER返回的SSL证书验证请求的结果
//    CURLINFO_CONTENT_LENGTH_DOWNLOAD - 从Content-Length: field中读取的下载内容长度
//    CURLINFO_CONTENT_LENGTH_UPLOAD - 上传内容大小的说明
//    CURLINFO_CONTENT_TYPE - 下载内容的Content-Type:值,NULL表示服务器没有发送有效的Content-Type:header


    //6、清理curl句柄
    curl_easy_cleanup(curl);

    //7、清理全局配置(只能调用一次)
    curl_global_cleanup();


    //8、操作文件内容
    //流指针移动到末尾
    fseek(file,0,SEEK_END);
    //返回当前流指针位置
    const long i = ftell(file);
    printf("文件长度:%d!\n",i);
    //计算完毕记得把流指针归位
    rewind(file);
    //申请一块能装下整个文件内容的内存区域
    char *a = (char *) malloc(i);
    fread(a, 1,i,file);
    printf("当前文件内容:%s\d",a);

    //记得释放申请的内存区域
    free(a);
    //关闭临时文件
    fclose(file);

    return 0;
}

结果:

Hello, World!

CURLINFO_TOTAL_TIME:2!

文件长度:74!

当前文件内容:{"errNo":"403","data": { "redDot": [ ], "newWord": [ ], "layer": [ ] }}d

如果需要操作json,则可以参考https://blog.csdn.net/sumengnan/article/details/123708177

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值