libcurl库使用

news2025/3/13 12:00:36

libcurl介绍

libcurl是一个跨平台的网络协议库,支持http, https,ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST,HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies和用户认证。

基本编程框架

  • 调用curl_global_init()初始化libcurl
  • 调用curl_easy_init()函数获得curl的指针
  • 调用curl_easy_setopt()设置传输选项
  • 调用curl_easy_perform()函数完成传输任务
  • 调用curl_easy_cleanup()释放内存

编程注意事项

  • curl_global_init():这个函数只能用一次。(其实在调用curl_global_cleanup函数后仍然可再用)。如果这个函数在curl_easy_init函数调用时还没调用,它讲由libcurl库自动调用,所以多线程下最好主动调用该函数以防止在线程中curl_easy_init时多次调用。虽然libcurl是线程安全的,但curl_global_init是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。
  • curl_global_cleanup():在结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数。虽然libcurl是线程安全的,但curl_global_cleanup是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。
  • curl_easy_init( )与curl_easy_cleanup():成对使用,用来初始化一个CURL的指针与释放CURL的指针。

常用的网站

该网站有libcurl的API的详细介绍,还有一些例子
The libcurl API

使用Postman生成代码

由于libcurl库的参数设置十分多,我们可以使Postman来生成代码。

  • 配置请求的参数,点击code
    在这里插入图片描述
  • 左边选择语言,右边就能生成对应语言的代码。
    在这里插入图片描述

例子

simple HTTP POST using the easy interface

#include <stdio.h>
#include <curl/curl.h>
 
int main(void)
{
  CURL *curl;
  CURLcode res;
 
  /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);
 
  /* get a curl handle */
  curl = curl_easy_init();
  if(curl) {
    /* First set the URL that is about to receive our POST. This URL can
       just as well be an https:// URL if that is what should receive the
       data. */
    curl_easy_setopt(curl, CURLOPT_URL, "http://postit.example.com/moo.cgi");
    /* Now specify the POST data */
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");
 
    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
 
    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  curl_global_cleanup();
  return 0;
}

HTTP PUT using CURLOPT_POSTFIELDS

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <curl/curl.h>
 
static const char olivertwist[]=
  "Among other public buildings in a certain town, which for many reasons "
  "it will be prudent to refrain from mentioning, and to which I will assign "
  "no fictitious name, there is one anciently common to most towns, great or "
  "small: to wit, a workhouse; and in this workhouse was born; on a day and "
  "date which I need not trouble myself to repeat, inasmuch as it can be of "
  "no possible consequence to the reader, in this stage of the business at "
  "all events; the item of mortality whose name is prefixed";
 
/* ... to the head of this chapter. String cut off to stick within the C90
   509 byte limit. */
 
/*
 * This example shows an HTTP PUT operation that sends a fixed buffer with
 * CURLOPT_POSTFIELDS to the URL given as an argument.
 */
 
int main(int argc, char **argv)
{
  CURL *curl;
  CURLcode res;
  char *url;
 
  if(argc < 2)
    return 1;
 
  url = argv[1];
 
  /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);
 
  /* get a curl handle */
  curl = curl_easy_init();
  if(curl) {
    struct curl_slist *headers = NULL;
 
    /* default type with postfields is application/x-www-form-urlencoded,
       change it if you want */
    headers = curl_slist_append(headers, "Content-Type: literature/classic");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
 
    /* pass on content in request body. When CURLOPT_POSTFIELDSIZE is not used,
       curl does strlen to get the size. */
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, olivertwist);
 
    /* override the POST implied by CURLOPT_POSTFIELDS
     *
     * Warning: CURLOPT_CUSTOMREQUEST is problematic, especially if you want
     * to follow redirects. Be aware.
     */
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
 
    /* specify target URL, and note that this URL should include a file
       name, not only a directory */
    curl_easy_setopt(curl, CURLOPT_URL, url);
 
    /* Now run off and do what you have been told! */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
 
    /* always cleanup */
    curl_easy_cleanup(curl);
 
    /* free headers */
    curl_slist_free_all(headers);
  }
 
  curl_global_cleanup();
  return 0;
}

文件上传

#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>

static size_t write_data(char *p, size_t size, size_t nmemb, void *userdata)
{
    char *buf = malloc(size * nmemb + 1);
    memcpy(buf, p, size * nmemb);
    buf[size * nmemb] = 0x00;
    log_debug(">>  %s", buf);
    free(buf);
    return size * nmemb;
}

/**
 * @brief 文件上传
 * @param path 文件路径
 * @param url url地址
 * @return 
 */
int http_file_upload(char *path, char *url)
{
    CURL *curl;
    CURLcode res;

    /* get a curl handle */
    curl = curl_easy_init();
    if (!curl) {
        return -1;
    }

    mgLog_debug("url: %s", url);
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);

	struct curl_slist *headers = NULL;
	headers = curl_slist_append(headers, "Content-Type: multipart/form-data");
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

    struct curl_httppost *post = NULL;
    struct curl_httppost *last = NULL;

    curl_formadd(&post, &last, CURLFORM_COPYNAME, "key", CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
    curl_formadd(&post, &last, CURLFORM_COPYNAME, "file", CURLFORM_FILE, path, CURLFORM_END);
    curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);

    /*执行数据请求*/
    res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        log_debug("curl_easy_perform() failed: %s", curl_easy_strerror(res));
    }
    
    curl_easy_cleanup(curl);
    curl_slist_free_all(headers);
    curl_formfree(post);

    return 0;
}

void test(void)
{
	curl_global_init(CURL_GLOBAL_ALL);
	http_file_upload("/tmp/test.txt","http://test.com/upload");
	curl_global_cleanup();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1104072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux加密和安全

sudo实现授权 添加 vim /etc/sudoers luo ALL(root) /usr/bin/mount /deb/cdrom /mnt/ 切换luo用户使用 sudo mount /dev/cdrom /mnt %sudo ALL(ALL:ALL) ALL %sudo 表示该规则适用于sudo用户组中的所有成员。 ALL(ALL:ALL) 表示可以在任何主机上&#xff0c;以任何用户身份来…

2023.10.17 关于 wait 和 notify 的使用

目录 引言 方法的使用 引入实例&#xff08;wait 不带参数版本&#xff09; wait 方法执行流程 wait 和 notify 组合实例 wait 带参数版本 notify 和 notifyAll 的区别 经典例题 总结 引言 线程最大的问题是抢占式执行&#xff0c;随机调度虽然线程在内核里的调度是随…

UITesting 界面测试

1. 创建界面测试视图 UITestingBootcampView.swift import SwiftUI/// 界面测试 ViewModel class UITestingBootcampViewModel: ObservableObject{let placeholderText: String "Add name here..."Published var textFiledText: String ""Published var…

CVE-2021-26084 漏洞分析

基础知识 Velocity .vm 结尾的文件一般为Velocity模板文件$action $action 是 velocity 上下⽂中的⼀个变量&#xff0c;⼀般在进⾏模板渲染前会设置到 context ⾥⾯。$action 是当前访问路由对应的具体 Action 类。$action.xxx 表⽰取对应 Action 类的 xxx 属性值 ${} 和 $!…

Kotlin中的字符串基本操作

字符串定义&#xff1a; val str: String "Hello World"val str1 "Hello World"获取字符串的长度&#xff1a; println(str.length)通过索引方式访问某个字符&#xff0c;索引从0开始&#xff1a; println(str[4])通过for循环迭代字符串&#xff1a; for…

Python-Python高阶技巧:闭包、装饰器、设计模式、多线程、网络编程、正则表达式、递归

版本说明 当前版本号[20231018]。 版本修改说明20231018初版 目录 文章目录 版本说明目录Python高阶技巧闭包简单闭包修改外部函数变量的值实现以下atm取钱的闭包实现了闭包注意事项 装饰器装饰器的一般写法&#xff08;闭包写法&#xff09;装饰器的语法糖写法 设计模式单例…

微信小程序中如何使用fontawesome6的免费图标

一、官网下载fontawesome6 Download Font Awesome Free or Pro | Font Awesome 二、使用transfer编码成Base64 transfer打开官网&#xff1a;Online font-face generator — Transfonter 首先先把刚刚下载的fontawesome6解压&#xff0c;将文件夹中的字体上传&#xff08;点…

发电机组负载测试的必要性

发电机组负载测试是确保发电机组能够在实际运行中稳定工作的重要步骤&#xff0c;负载测试可以模拟发电机组在不同负载条件下的工作情况&#xff0c;评估其性能和稳定性。负载测试可以验证发电机组在不同负载条件下的性能表现&#xff0c;通过模拟实际使用情况评估发电机组的输…

【Flutter】第一篇基础:站在一名web前端开发者的角度看代框架

Flutter Flutter 是一个跨平台的 UI 工具集&#xff0c;它的设计初衷&#xff0c;就是允许在各种操作系统上复用同样的代码&#xff0c;例如 iOS 和 Android&#xff0c;同时让应用程序可以直接与底层平台服务进行交互。如此设计是为了让开发者能够在不同的平台上&#xff0c;…

怎么把m4v转换为mp4?

怎么把m4v转换为mp4&#xff1f;M4V是一种由苹果公司开发的视频文件格式&#xff0c;该格式可以在苹果公司的iTunes和QuickTime软件中播放。M4V格式本质上与MP4格式相似&#xff0c;但M4V通常包括了用于数字版权管理&#xff08;DRM&#xff09;的保护措施&#xff0c;以控制该…

【笔记-OrCAD】WARNING(ORCAP-36038)解决办法

问题描述&#xff1a; OrCAD16.6绘制好原理图后&#xff0c;点击“*.dsn”文件可以生成网表&#xff0c;在存放原理图的文件内找到allegro文件夹&#xff0c;用记事本打开netlist.log文件&#xff0c;可以看到具体的警告原因&#xff0c;例如&#xff1a; WARNING(ORCAP-36038)…

优雅而高效的JavaScript—— Class 和模块化

&#x1f60a;博主&#xff1a;小猫娃来啦 &#x1f60a;文章核心&#xff1a;优雅而高效的JavaScript—— Class 和模块化 文章目录 引言Class 的概念和用法Class 的定义Class 的继承Class 的静态方法和属性 模块化的概念和用法模块的导出和导入模块的默认导出和命名导出模块的…

SpringCloud: sentinel链路限流

一、配置文件要增加 spring.cloud.sentinel.webContextUnify: false二、在要限流的业务方法上使用SentinelResource注解 package cn.edu.tju.service;import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockExcept…

CVPR、ICCV、ECCV论文获取

CVPR每年召开&#xff0c;ICCV两年一次 链接地址 ECCV两年一开 链接地址

10. 机器学习-评测指标

Hi,你好。我是茶桁。 之前的课程中&#xff0c;我们学习了两个最重要的回归方法&#xff0c;一个线性回归&#xff0c;一个逻辑回归。也讲解了为什么学习机器学习要从逻辑回归和线性回归讲起。因为我们在解决问题的时候&#xff0c;有限选择简单的假设&#xff0c;越复杂的模型…

十七、文件(1)

本章概要 文件和目录路径 选取路径部分片段路径分析Paths 的增减修改 目录 在丑陋的 Java I/O 编程方式诞生多年以后&#xff0c;Java终于简化了文件读写的基本操作。 打开并读取文件对于大多数编程语言来说是非常常用的&#xff0c;由于 I/O 糟糕的设计以至于很少有人能够在不…

第七章 排序

第七章 排序 概述插入排序交换排序冒泡排序快速排序 选择排序直接选择排序堆排序 归并排序有序序列合并二路归并排序 小试牛刀 概述 排序就是将一组对象按照规定的次序&#xff08;升序或降序等&#xff09;重新排列的过程&#xff0c;往往为检索服务相同键值的两个记录在排序…

索引背后的数据结构——B+树

为什么要使用B树&#xff1f; 可以进行数据查询的数据结构有二叉搜索树、哈希表等。对于前者来说&#xff0c;树的高度越高&#xff0c;进行查询比较的时候访问磁盘的次数就越多。而后者只有在数据等于key值的时候才能进行查询&#xff0c;不能进行模糊匹配。所以出现了B树来解…

SQL数据库管理工具RazorSQL mac中文版特点与功能

RazorSQL mac是一款功能强大的SQL数据库管理工具&#xff0c;它支持多种数据库&#xff0c;包括MySQL、Oracle、Microsoft SQL Server、SQLite、PostgreSQL等。 RazorSQL mac 软件特点和功能 多种数据库支持&#xff1a;RazorSQL支持多种数据库&#xff0c;用户可以通过一个工…

故障预测与健康管理(PHM)在工业领域的发展前景

故障预测与健康管理&#xff08;PHM&#xff09;作为一种关键技术&#xff0c;已经在工业领域引起了广泛的关注和应用。PHM利用传感器、数据科学和智能算法等技术手段&#xff0c;通过实时监测和分析设备和系统的状态&#xff0c;提前发现潜在故障&#xff0c;并采取适当的维修…