curl的交叉编译及使用(unbntu->开发板)


前言

Curl是一个开源的命令行工具和库,用于进行网络数据传输。它支持多种协议,包括HTTP、FTP、SMTP、POP3等。Curl可以用来发送HTTP请求、下载文件、上传文件、进行文件传输等。


一、curl的特点

  • 多协议支持:Curl支持多种网络协议,包括HTTP、HTTPS、FTP、SMTP、POP3等。
  • SSL支持:Curl支持通过HTTPS进行安全的数据传输,并且可以验证服务器的证书。
  • 代理支持:Curl可以通过代理服务器发送请求,支持HTTP、HTTPS、FTP等代理。
  • 断点续传:Curl支持断点续传,可以在下载文件时恢复中断的传输。
  • Cookie支持:Curl可以自动处理和发送Cookie,方便进行用户认证和会话管理。
  • 数据上传:Curl可以用来上传文件,支持多种文件传输协议。 自定义请求:Curl提供了丰富的选项,可以自定义请求头、请求方法、请求体等。

二、交叉编译

1.前期准备工作

  1. 下载curl 点击这里去下载
    在这里插入图片描述
  2. 解压缩curl
    unzip curl-8.2.1.zip
  3. 查询cmake版本
    curl需要至少3.7.0版本的cmake,
    root@ubuntu:/# cmake --version
    cmake version 3.5.1
    
    CMake suite maintained and supported by Kitware (kitware.com/cmake).
    

2.手动更新cmake版本(cmake版本不小于3.7.0的可以看下一步)

  1. 点击这里 去下载
  2. 我下载的是3.7版本的cmake cmake-3.7.0-Linux-x86_64.tar.gz
  3. 解压缩:tar -zxvf cmake-3.7.0-Linux-x86_64.tar.gz
  4. 备份之前的cmake
    mv /usr/bin/cmake /usr/bin/cmake_3.5.1.bak
  5. 替换新的cmake(需要复制cmake到share路径下)
    cd cmake-3.7.0-Linux-x86_64
    cp bin/cmake /usr/bin
    cp share/cmake-3.7 /usr/share -rf
    
  6. 查询cmake版本
    root@ubuntu:/# cmake --version
    cmake version 3.7.0
    
    CMake suite maintained and supported by Kitware (kitware.com/cmake).
    

3.交叉编译curl

  1. ./configure --host=arm-linux-gnueabihf --prefix=/home/curl-8.2.1/bin -without-ssl

    • –host指定的是交叉编译工具链的前缀,需要全局可以搜索到
      在这里插入图片描述
    • –prefix 指定make install时的安装路径
    • -without-ssl 禁用ssl(会无法使用https) 我不需要就禁用了 如果要用需要交叉编译ssl,后续用到了我会再出一篇教程
    • 执行完成后会有使能了模块的打印说明
      • 可以看到 https后面的no,说明没有使能.
      • http1后面的enabled 说明使能了
      configure: Configured to build curl/libcurl:
      
        Host setup:       arm-unknown-linux-gnueabihf
        Install prefix:   /home/curl-8.2.1/bin
        Compiler:         arm-linux-gnueabihf-gcc
         CFLAGS:          -Werror-implicit-function-declaration -O2 -Wno-system-headers -pthread
         CPPFLAGS:
         LDFLAGS:
         LIBS:
      
        curl version:     8.2.1
        SSL:              no      (--with-{openssl,gnutls,nss,mbedtls,wolfssl,schannel,secure-transport,amissl,bearssl,rustls} )
        SSH:              no      (--with-{libssh,libssh2})
        zlib:             no      (--with-zlib)
        brotli:           no      (--with-brotli)
        zstd:             no      (--with-zstd)
        GSS-API:          no      (--with-gssapi)
        GSASL:            no      (libgsasl not found)
        TLS-SRP:          no      (--enable-tls-srp)
        resolver:         POSIX threaded
        IPv6:             enabled
        Unix sockets:     enabled
        IDN:              no      (--with-{libidn2,winidn})
        Build libcurl:    Shared=yes, Static=yes
        Built-in manual:  enabled
        --libcurl option: enabled (--disable-libcurl-option)
        Verbose errors:   enabled (--disable-verbose)
        Code coverage:    disabled
        SSPI:             no      (--enable-sspi)
        ca cert bundle:   no
        ca cert path:
        ca fallback:
        LDAP:             no      (--enable-ldap / --with-ldap-lib / --with-lber-lib)
        LDAPS:            no      (--enable-ldaps)
        RTSP:             enabled
        RTMP:             no      (--with-librtmp)
        PSL:              no      (libpsl not found)
        Alt-svc:          enabled (--disable-alt-svc)
        Headers API:      enabled (--disable-headers-api)
        HSTS:             no      (--enable-hsts)
        HTTP1:            enabled (internal)
        HTTP2:            no      (--with-nghttp2, --with-hyper)
        HTTP3:            no      (--with-ngtcp2 --with-nghttp3, --with-quiche, --with-msh3)
        ECH:              no      (--enable-ech)
        WebSockets:       no      (--enable-websockets)
        Protocols:        DICT FILE FTP GOPHER HTTP IMAP MQTT POP3 RTSP SMTP TELNET TFTP
        Features:         AsynchDNS IPv6 Largefile UnixSockets alt-svc threadsafe
      
      
  2. make

  3. make install

    • 完成后可以去**–prefix**指定的目录下去查看 生成的文件
    • bin/curl 是可以在该平台执行的工具
    • lib/libcurl* 是静态与动态链接库,配合include文件夹下面的头文件可以编译到c/c++程序中
      curl install文件夹

三、在c++中使用并下载文件,同时打印下载百分比

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

struct CurlProgressData
{
    double  last_progress;
    double* para_in_progress;
    FILE*   fp;
};

/*私有函数 写文件*/
size_t scurl_write_file(void* ptr, size_t size, size_t nmemb, FILE* stream)
{
    return fwrite(ptr, size, nmemb, stream);
}
/*私有函数 进度回调函数*/
int scurl_progress_callback(void* clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
    struct CurlProgressData* progress = (struct CurlProgressData*)clientp;
    if (dltotal > 0)
    {
        double current_progress = (double)dlnow / (double)dltotal * 100.0;

        if ((current_progress - progress->last_progress >= 1.0) || (current_progress == 100.0))
        {
            printf("Download Progress: %.2f%%\n", current_progress);
            progress->last_progress = current_progress;
            if (progress->para_in_progress)
            {
                *progress->para_in_progress = current_progress;
            }
        }
    }
    return 0;
}
/**
***************************************************************************
 函 数 名  : curlDownloadFileProgress
 功能描述  : 去url地址下载文件并保存为saveName,同时记录下载进度,保留小数点后两位
 输入参数  : const char* url           url地址 完整的 例:http://xxx.com/xxx/xx.zip
           const char* saveName    保存的文件名称,需要是全路径 例:/tmp/load.zip
           double* process         进度
 返 回 值  : bool true:下载成功 false:下载失败
 修改历史      :
    日    期    : 2023年8月18日
    作    者    : xzf
    修改内容    : 新生成函数
*****************************************************************************/
bool curlDownloadFileProgress(const char* url, const char* saveName, double* process)
{
    CURL*                   curl;
    FILE*                   fp;
    CURLcode                res;
    bool                    ret      = false;
    struct CurlProgressData progress = {0.0, NULL, NULL};
    progress.para_in_progress        = process;

    H_LOG_DEBUG("     url[%s]", url);
    H_LOG_DEBUG("saveName[%s]", saveName);
    
    curl_global_init(CURL_GLOBAL_DEFAULT);
    
    curl = curl_easy_init();
    if (!curl)
    {
        H_LOG_ERROR("curl_easy_init() failed");
        return ret;
    }

    curl_easy_setopt(curl, CURLOPT_URL, url);
    // 打开文件用于保存下载的内容
    fp = fopen(saveName, "wb");
    if (fp)
    {
        // 设置写入数据的回调函数和文件指针
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, scurl_write_file);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

        // 设置进度回调函数和进度数据指针
        curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, scurl_progress_callback);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
        curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &progress);

        // 执行下载操作
        res = curl_easy_perform(curl);
        if (res != CURLE_OK)
        {
            H_LOG_ERROR("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        }
        else
        {
            *progress.para_in_progress = 100.0;
            ret                        = true;
        }

        // 关闭文件
        fclose(fp);
    }
    else
    {
        H_LOG_ERROR("fopen(%s) failed", saveName);
    }
    curl_easy_cleanup(curl);
    
    curl_global_cleanup();
    return ret;
}

void main()
{
	double upgrade_plan = 0;
	bool ret = curlDownloadFileProgress("http://123/api/version/Get","/tmp/upgrade.zip",&upgrade_plan);
}

四、在c++中使用并执行get方法获取返回内容

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

/*私有函数 写缓冲器*/
size_t scurl_write_buffer(void* ptr, size_t size, size_t nmemb, void* userdata)
{
    size_t totalSize = size * nmemb;
    char** buffer    = (char**)userdata;

    // 计算当前缓冲区的大小
    size_t currentSize = 0;
    if (*buffer)
    {
        currentSize = strlen(*buffer);
    }

    // 分配新的缓冲区,并将数据追加到缓冲区中
    char* newBuffer = (char*)realloc(*buffer, currentSize + totalSize + 1);
    if (newBuffer)
    {
        memcpy(newBuffer + currentSize, ptr, totalSize);
        newBuffer[currentSize + totalSize] = '\0';
        *buffer                            = newBuffer;
    }

    return totalSize;
}

/*****************************************************************************
 函 数 名  : curlGetUrlTobuf
 功能描述  : 执行get命令 可选择携带参数,相应内容放在para中
 输入参数  : const char* url   url地址 例:http://xx.xx.com
           const char* para  携带的参数注意格式?A=B&C=D
           char** response   响应的内容,传递进来的需要为NULL,使用完成后需要手动free释放
 返 回 值  : bool  true:请求成功 false:请求失败
 修改历史      :
    日    期    : 2023年8月18日
    作    者    : xzf
    修改内容    : 新生成函数

*****************************************************************************/
bool curlGetUrl(const char* url, const char* para, char** response)
{
    CURL*    curl;
    CURLcode res;
    bool     ret = false;

    H_LOG_DEBUG("url[%s]", url);
    if (para)
    {
        H_LOG_DEBUG("para[%s]", para);
    }
    char* resp_buffer = *response;

    if (*response)
    {
        H_LOG_ERROR("response != nullptr");
        free(*response);
        *response = nullptr;
        H_LOG_ERROR("reset response success");
    }


    curl_global_init(CURL_GLOBAL_DEFAULT);


    curl = curl_easy_init();
    if (!curl)
    {
        H_LOG_ERROR("curl_easy_init() failed");
        return ret;
    }

    // 设置基本的URL
    curl_easy_setopt(curl, CURLOPT_URL, url);

    if (para)
    {
        // 获取当前的URL
        char* url;
        curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);

        // 拼接参数到URL上
        char full_url[256];
        sprintf(full_url, "%s%s", url, para);
        curl_easy_setopt(curl, CURLOPT_URL, full_url);
    }

    // 创建缓冲区,并将其传递给写入回调函数
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, scurl_write_buffer);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp_buffer);

    // 执行GET请求
    res = curl_easy_perform(curl);

    // 检查请求是否成功
    if (res != CURLE_OK)
    {
        H_LOG_ERROR("请求失败:%s\n", curl_easy_strerror(res));
        if (resp_buffer)
        {
            free(resp_buffer);
            resp_buffer = nullptr;
        }
    }
    else
    {
        ret = true;
        // 打印存储的数据
        *response = resp_buffer;
        H_LOG_DEBUG("收到的数据:[%s]", *response);
    }
    curl_easy_cleanup(curl);
    
    curl_global_cleanup();

    return ret;
}

void main()
{
    char* response = NULL;
	bool ret = curlGetUrl("http://123/api/version/Get","?A=B&C=D",&response );
	if(ret)
	{
		//...
		free(response);
	}
}

五、简单的curl工具使用,很简单

	# 下载一个图片(get方法)
	./curl http://www.aaa.bbb.com/get/img.jpg

总结

好了,关于curl工具的分享就到这里了,大家有什么问题欢迎评论,我看到了会第一时间回复

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在Linux使用curl进行交叉编译,首先需要安装相关的交叉编译工具链。根据目标平台选择适当的工具链,如ARM、MIPS等。然后,下载curl的源代码包并解压。 进入curl源码目录后,可以配置编译参数。使用./configure命令,通过指定交叉编译工具链的位置和参数,来进行交叉编译的配置。例如: ``` ./configure --host=交叉编译工具链的前缀 ``` 其中,"--host"参数后面跟的是经过交叉编译工具链前缀,如arm-linux-gnueabi、mips-linux-gnu等。这样配置之后,就可以使用交叉编译器来编译curl了。 配置完成后,运行make命令进行编译。编译完成后,即生成了交叉编译后的curl可执行文件。 最后,将生成的可执行文件拷贝到目标平台上进行运行测试即可。 总结起来,通过安装交叉编译工具链、配置编译参数,以及使用make命令进行编译,就可以在Linux下完成curl交叉编译。 ### 回答2: 在Linux系统下,交叉编译是指在一台主机上用特定工具链编译生成适用于另一种主机架构的可执行程序。对于curlLinux下的交叉编译,以下是一些步骤: 首先,我们需要设置交叉编译环境。这包括安装交叉编译工具链和交叉编译的目标架构的头文件与库。 然后,我们需要下载curl的源代码。可以从curl的官方网站下载最新版本的源代码。 接下来,我们需要根据交叉编译工具链的要求配置curl的编译选项。这可能涉及到指定目标架构、链接选项、头文件和库的路径等。 然后,我们可以运行configure命令来生成适用于交叉编译环境的Makefile。configure命令会根据主机架构、编译选项等自动配置Makefile。 接着,我们可以运行make命令进行编译。make命令会根据Makefile中的指令来编译生成可执行程序。在编译过程中,可能会出现一些依赖问题需要解决,比如缺少某些库文件。 最后,我们可以运行make install命令将编译生成的可执行程序安装到目标机器中。 需要注意的是,根据交叉编译工具链和目标架构的不同,具体的交叉编译过程可能会有所差异。因此,在进行交叉编译前,建议阅读相关文档或参考其他资源,以便更好地理解和掌握交叉编译的步骤和注意事项。 ### 回答3: 在Linux下进行curl交叉编译,需要以下几个步骤: 1. 安装交叉编译工具链:首先需要在Linux系统中安装适合目标平台的交叉编译工具链。根据目标平台的不同,可以选择不同的工具链,例如gcc、g++等。 2. 下载curl源代码:从curl的官方网站上下载最新的curl源代码包,并解压到本地。 3. 配置交叉编译环境:打开终端,进入解压后的curl源代码目录下,执行以下命令: ``` export CC=交叉编译器路径 export CXX=交叉编译器路径 export AR=交叉编译器路径-ar export RANLIB=交叉编译器路径-ranlib export LD=交叉编译器路径-ld export STRIP=交叉编译器路径-strip export CPPFLAGS="-I交叉编译器路径/include" export LDFLAGS="-L交叉编译器路径/lib" ``` 替换上述命令中的“交叉编译器路径”为实际的交叉编译工具链路径。 4. 配置编译选项:执行以下命令配置编译选项: ``` ./configure --host=目标平台 --prefix=安装路径 ``` 其中,目标平台是指要将curl交叉编译到的目标硬件平台,安装路径是指将编译后的curl安装到的目录。根据实际的需求进行配置。 5. 编译和安装:执行以下命令开始编译和安装: ``` make make install ``` 编译过程可能需要一些时间,等待编译完成后,curl将被安装到指定的安装路径下。 通过以上步骤,我们可以在Linux下成功进行curl交叉编译。在配置交叉编译环境时,需要注意交叉编译器的选择和路径的配置,确保编译工具链已正确安装,并设置正确的编译选项。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值