C++ 使用CURL开源库实现Http/Https的get/post请求进行字串和文件传输
CURL开源库介绍
CURL 是一个功能强大的开源库,用于在各种平台上进行网络数据传输。它支持众多的网络协议,像 HTTP、HTTPS、FTP、SMTP 等,能让开发者方便地在程序里实现与远程服务器的通信。
CURL 可以在 Windows、Linux、macOS 等多种操作系统上使用;
CURL 支持多种网络协议,能处理复杂的网络请求,如设置请求头、处理 cookies、上传和下载文件等。
使用前,编译CURL 源码,生成动态库,引入时包括头文件一起,网上也有别人已经编译好的现成的库可以下载使用。
生成的库:
在你要使用的项目里加上curl的头文件
#include <curl\curl.h>
这下你就可以使用CURL里的接口完成功能了。
CURL常用的接口说明:
- 初始化与清理相关的接口:
- curl_easy_init()
功能:创建并初始化一个新的 CURL 句柄,用于后续的网络操作。这个句柄就像一个会话的载体,后续的请求设置和执行都围绕它展开。
返回值:成功时返回一个指向新创建的 CURL 句柄的指针;失败则返回 NULL。 - curl_easy_cleanup(CURL *handle)
功能:释放 CURL 句柄占用的所有资源,包括内存、网络连接等。在使用完 CURL 句柄后,必须调用此函数以避免资源泄漏。
参数:handle 是之前通过 curl_easy_init() 得到的 CURL 句柄。
- 请求选项设置相关的接口:
- curl_easy_setopt(CURL *handle, CURLoption option, …)
功能:设置 CURL 句柄的各种选项,这些选项可以控制请求的各个方面,如请求的 URL、请求方法、请求头、回调函数等。
参数:
handle:CURL 句柄。
option:CURLoption 类型的常量,指定要设置的选项。
可变参数:根据不同的 option,需要传入相应的参数值。
常用 option 有:
CURLOPT_URL:设置请求的 URL。
CURLOPT_POST:将请求方法设置为 POST。
CURLOPT_HTTPHEADER:设置请求头。
CURLOPT_POSTFIELDS:设置 POST 请求的数据。 - curl_slist_append(struct curl_slist *list, const char *string)
功能:用于构建一个链表来存储请求头信息。每次调用该函数可以将一个新的请求头字符串添加到链表中。
参数:
list:指向 curl_slist 链表的指针,如果是第一次添加,可传入 NULL。
string:要添加的请求头字符串,格式为 Header-Name: Header-Value。
返回值:返回更新后的链表指针。
- 回调函数设置相关的接口:
- CURLOPT_WRITEFUNCTION 和 CURLOPT_WRITEDATA
功能:CURLOPT_WRITEFUNCTION:设置一个回调函数,当服务器返回响应数据时,CURL 会调用该回调函数来处理响应数据。
CURLOPT_WRITEDATA:传递一个用户自定义的指针给回调函数,用于在回调函数中存储或处理数据。 - CURLOPT_READFUNCTION 和 CURLOPT_READDATA
功能:CURLOPT_READFUNCTION:设置一个回调函数,用于在发送数据时从用户提供的数据源中读取数据。
CURLOPT_READDATA:传递一个用户自定义的指针给回调函数,用于标识数据源。
- 多线程与异步操作相关的接口:
- curl_multi_init()
功能:初始化一个 CURLM 句柄,用于多线程或异步的网络操作。该句柄可以管理多个 CURL 句柄,实现并发请求。
返回值:成功时返回一个新的 CURLM 句柄指针;失败返回 NULL。 - curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle)
功能:将一个 CURL 句柄添加到 CURLM 句柄管理的句柄列表中,以便进行并发处理。
参数:
multi_handle:CURLM 句柄。
easy_handle:要添加的 CURL 句柄。 - curl_multi_perform(CURLM *multi_handle, int *still_running)
功能:在 CURLM 句柄管理的所有 CURL 句柄上执行网络操作。该函数会尝试处理尽可能多的请求,并返回仍在运行的请求数量。
参数:
multi_handle:CURLM 句柄。
still_running:指向一个整数的指针,用于存储仍在运行的请求数量。 - curl_multi_remove_handle(CURLM *multi_handle, CURL *easy_handle)
功能:从 CURLM 句柄管理的句柄列表中移除一个 CURL 句柄。
参数:
multi_handle:CURLM 句柄。
easy_handle:要移除的 CURL 句柄。 - curl_multi_cleanup(CURLM *multi_handle)
功能:释放 CURLM 句柄占用的所有资源。在使用完 CURLM 句柄后,必须调用此函数进行清理。
参数:multi_handle 是 CURLM 句柄。
接口流程使用:
简单的同步调用模式的使用流程:
- 调用curl_global_init()初始化libcurl ;
- 调用curl_easy_init()函数得到 easy;
- interface型指针 调用curl_easy_setopt()设置传输选项;
- 根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务;
- 调用curl_easy_perform()函数完成传输任务,返回错误码 ;
- 调用curl_easy_cleanup()释放内存;
- 调用curl_global_cleanup() (可以不用调用);
在整过过程中设置curl_easy_setopt()参数是最关键的,了解相关参数及对应作用很重要。
举例说明CURL的调用实现
//http回调写函数
static size_t CurlWriteBuffer(char *buffer, size_t size, size_t nmemb, std::string* stream)
{//第二个参数为每个数据的大小,第三个为数据个数,最后一个为接收变量size_t sizes = size*nmemb;if(stream == NULL) return 0;stream->append(buffer,sizes);return sizes;
}//http发送封装
int HttpClient::posturl(std::string& msg, std::string& url, bool IsSSL)
{CURL* pCurl=NULL; //一个libcurl的handleCURLcode res; //返回状态码std::string response; //返回信息curl_global_init(CURL_GLOBAL_ALL); //全局初始化pCurl = curl_easy_init(); //创建一个handle//设置请求头struct curl_slist* pHeader = NULL;//传json格式,字符编码为utf8header_ = curl_slist_append(pHeader ,"Content-Type: application/json;charset=utf-8");//添加请求头到handlecurl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pHeader );//设置URLcurl_easy_setopt(pCurl, CURLOPT_URL, url.c_str()); CURLOPT_WRITEFUNCTION 将后继的动作交给write_data函数处理curl_easy_setopt(pCurl,CURLOPT_POSTFIELDS,msg.c_str()); //post请求消息数据 curl_easy_setopt(pCurl,CURLOPT_POSTFIELDSIZE,msg.length()); //消息长度curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, CurlWriteBuffer); //回调函数curl_easy_setopt(pCurl,CURLOPT_WRITEDATA,&response); //数据接收变量curl_easy_setopt(pCurl,CURLOPT_TIMEOUT,m_settinginfo.m_http_timeout); //连接超时时间//不支持ssl验证if(m_settinginfo.m_ssl == 0){curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0);//设定为不验证证书和HOSTcurl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0);}else{// 配置 https 请求所需证书if (m_settinginfo.m_ssl == 1) //ssl单向验证,不验证服务器{curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0L); }else{//双向验证curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 1L);curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0);curl_easy_setopt(pCurl,CURLOPT_CAINFO,ca_info.ca_path.c_str()); }//设置客户端信息curl_easy_setopt(pCurl, CURLOPT_SSLCERT, ca_info.client_cert_path.c_str());curl_easy_setopt(pCurl,CURLOPT_SSLCERTTYPE,"PEM"); curl_easy_setopt(pCurl, CURLOPT_SSLKEY, ca_info.client_key_path.c_str());curl_easy_setopt(pCurl,CURLOPT_SSLKEYTYPE,"PEM"); //如果客户端证书密钥使用密码加密,设置加密密码//curl_easy_setopt(pCurl, CURLOPT_KEYPASSWD, "your_key_password");}//执行http连接res = curl_easy_perform(pCurl);//清除消息头curl_slist_free_all(pHeader);//清除handlecurl_easy_cleanup(pCurl);return 0;
}
再看一段完整的CURL封装成get,post等形式,进行字串传输和文件上传的请求,可以直接拿去使用。
//Http的Get请求
int HttpClient::ExecuteGetRequestCURL(const char* strUrl, const char* pszGet, const char* pszCookie, int nTimeOut)
{CURLcode res;m_strResponse = "";struct curl_slist* headers = NULL;CURL* curl = curl_easy_init();if (NULL == curl){return CURLE_FAILED_INIT;}std::string strOutData = strUrl;strOutData += pszGet;curl_easy_setopt(curl, CURLOPT_URL, strOutData.c_str());curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&m_strResponse);/*** 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。* 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。*/curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);//连接超时设置10s,数据请求超时设置60scurl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);res = curl_easy_perform(curl);if (res != CURLE_OK)m_strResponse = "";curl_easy_cleanup(curl);return res;
}
//Http的post请求
int HttpClient::ExecutePostRequestCURL(const char* strUrl, const char* pszKey, const char* pszPost, const char* pszCookie, int nTimeOut)
{CURLcode res;m_strResponse = "";CURL* curl = curl_easy_init();if (NULL == curl){return CURLE_FAILED_INIT;}///struct curl_slist* headerlist = NULL;struct curl_httppost* formpost = NULL;struct curl_httppost* last = NULL;//headerlist = curl_slist_append(headerlist, "Content-Type:application/json;charset=UTF-8");//curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);res = curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate, br");//设置CURLOPT_ACCEPT_ENCODING (7.21.8之前为CURLOPT_ENCODING )if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_formadd(&formpost, &last, CURLFORM_PTRNAME, pszKey, CURLFORM_PTRCONTENTS, pszPost, CURLFORM_END); //以这种方式上传可以避免特殊字符被改变if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); //构造post参数 if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}/curl_easy_setopt(curl, CURLOPT_URL, strUrl);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}//curl_easy_setopt(curl, CURLOPT_POST, 1);//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pszPost);curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&m_strResponse);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}if ((pszCookie != NULL)&&(strlen(pszCookie)>0)){ curl_easy_setopt(curl, CURLOPT_COOKIEFILE, (void *)&pszCookie);curl_easy_setopt(curl, CURLOPT_COOKIEJAR, (void *)&pszCookie);}//连接超时设置,数据请求超时设置curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);res = curl_easy_perform(curl);if (res != CURLE_OK){m_strResponse = "";// 获取详细错误信息const char* szErr = curl_easy_strerror(res);fprintf(stderr, "curl_easy_perform() failed: %s\n", szErr);}// 清空curl_easy_cleanup(curl);// 释放表单curl_formfree(formpost);// 释放表头curl_slist_free_all (headerlist); return res;
}//https的Get请求
int HttpClient::ExecuteHttpsGetCURL(const std::string & strUrl, const char* pszGet, const char * pCaPath, int nTimeOut)
{CURLcode res;CURL* curl = curl_easy_init();if (NULL == curl){return CURLE_FAILED_INIT;}std::string strOutData = strUrl;strOutData += pszGet;curl_easy_setopt(curl, CURLOPT_URL, strOutData.c_str());curl_easy_setopt(curl, CURLOPT_HEADER, 0 ); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&m_strResponse);curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);if (NULL == pCaPath){curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);}else{curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);}curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);//curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);//curl_easy_setopt(curl,CURLOPT_TRANSFERTEXT,1); res = curl_easy_perform(curl);if (res != CURLE_OK)m_strResponse = "";curl_easy_cleanup(curl);return res;
}//https的Post请求
int HttpClient::ExecuteHttpsPostCURL(const std::string& strUrl, const std::string& strKey, const std::string& strPost, const std::string& strCookie, const char* pCaPath, int nTimeOut)
{CURLcode res;CURL* curl = curl_easy_init();if (NULL == curl){return CURLE_FAILED_INIT;}///struct curl_slist* headers = NULL;struct curl_httppost* post = NULL;struct curl_httppost* last = NULL;curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate, br");//设置CURLOPT_ACCEPT_ENCODING (7.21.8之前为CURLOPT_ENCODING )curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);curl_formadd(&post, &last, CURLFORM_PTRNAME, strKey.c_str(), CURLFORM_PTRCONTENTS, strPost.c_str(), CURLFORM_END); //以这种方式上传可以避免特殊字符被改变curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); //构造post参数curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
// curl_easy_setopt(curl, CURLOPT_POST, 1);
// curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&m_strResponse);curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60*5);//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60*5);if (strCookie.length()>0){curl_easy_setopt(curl, CURLOPT_COOKIEFILE, (void *)&strCookie);curl_easy_setopt(curl, CURLOPT_COOKIEJAR, (void *)&strCookie);}if (NULL == pCaPath){//curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);//curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);}else{//缺省情况就是PEM,所以无需设置,另外支持DER//curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);}curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 20);curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);curl_easy_setopt(curl, CURLOPT_SSLVERSION, 3);res = curl_easy_perform(curl);curl_easy_cleanup(curl);return res;
}static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid)
{ std::string* str = reinterpret_cast<std::string*>(lpVoid);if (NULL == str || NULL == buffer){return -1;}char* pData = reinterpret_cast<char*>(buffer);str->append(pData, size * nmemb);return nmemb;
}long HttpClient::GetRespone(char* pszResponse, long &lRespLen)
{long lRet = 0;if (m_strResponse.length() <= 0){lRet = 1;goto err;}if (pszResponse == NULL){lRespLen = m_strResponse.length();goto err;}if (lRespLen < m_strResponse.length()){lRet = 1;goto err;}memset(pszResponse, 0, lRespLen);memcpy(pszResponse, m_strResponse.c_str(), m_strResponse.length());lRespLen = m_strResponse.length();
err:return lRet;
}long HttpClient::GetFileNameAndExt(const std::string & strFilePath,std::string & strFileName,std::string & strFileExt)
{long lRet = 0;strFileExt = "";strFileName = "";int nPos = strFilePath.rfind('.');if (nPos == -1){lRet = CURLE_FAILED_INIT; //文件不存在goto err;}strFileExt = strFilePath.substr(nPos+1, strFilePath.length());nPos = strFilePath.rfind('\\');if (nPos == -1){nPos = strFilePath.rfind('/');if (nPos == -1){strFileName = strFilePath;goto err;}}strFileName = strFilePath.substr(nPos+1, strFilePath.length());
err:return lRet;
}
//Http的post传文件请求
//strParamName是"bindingSeal",strParamVal值是对应的json包,strParamName2是"sealImages",strParamVal2值是图片名称
long HttpClient::HttpUploadFileCURL(LPCTSTR strUrl, const string& strFilePath, const string& strParamName, const string& strParamVal, const string& strParamName2, const string& strParamVal2, string& strResponse)
{CURL* curl;CURLcode res;long lRet = 0;std::string strFileName;std::string strFileExt;StringTool strTool;string strCRUL = strTool.WideToAsc(strUrl);lRet = GetFileNameAndExt(strFilePath, strFileName, strFileExt);if (lRet != 0)goto err;curl = curl_easy_init();struct curl_httppost* post = NULL;struct curl_httppost* last = NULL;if (curl == NULL){lRet = CURLE_FAILED_INIT;goto err;}curl_easy_setopt(curl, CURLOPT_URL, (char *)strCRUL.c_str()); //指定url//form-data key(path) 和 value(device_cover)curl_formadd(&post, &last, CURLFORM_PTRNAME, strParamName.c_str()/*"parma"*/, CURLFORM_PTRCONTENTS, strParamVal.c_str(), CURLFORM_END);curl_formadd(&post, &last, CURLFORM_PTRNAME, strParamName2.c_str(), CURLFORM_FILE, strFilePath.c_str(),CURLFORM_FILENAME, strFileName.c_str(),CURLFORM_CONTENTTYPE,"image/png", CURLFORM_END);//curl_formadd(&post, &last, CURLFORM_PTRNAME, strParamName2.c_str(), CURLFORM_FILE, strFilePath.c_str(),CURLFORM_FILENAME, strFileName.c_str(),CURLFORM_CONTENTTYPE,"image/PNG", CURLFORM_END);curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); //构造post参数 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); //绑定相应curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); //绑定响应内容的地址res = curl_easy_perform(curl); //执行请求if(res == 0){curl_easy_cleanup(curl); lRet = res;goto err;}else{lRet = res;goto err;}lRet = res;err:return lRet;
}
相关文章:

C++ 使用CURL开源库实现Http/Https的get/post请求进行字串和文件传输
CURL开源库介绍 CURL 是一个功能强大的开源库,用于在各种平台上进行网络数据传输。它支持众多的网络协议,像 HTTP、HTTPS、FTP、SMTP 等,能让开发者方便地在程序里实现与远程服务器的通信。 CURL 可以在 Windows、Linux、macOS 等多种操作系…...

面试题-SpringCloud的启动流程
关键词 prepareEnvironmentBootstrapApplicationListenerBootStrap Context(启动应用上下文)Environment中bootstrap属性 面试回答 引入SpringCloud相关组件后,均会引入一个spring-cloud-context的依赖包,这个项目的META-INF/s…...

MySQL基础知识
目录 一.什么是MySQL 二.分布式系统中的身份转换 三.MySQL是如何存储数据的 四.什么是数据库的命令 一.什么是MySQL MySQL是一个“客户端(client) - 服务器(server)”结构的软件(数据库软件)。 客户端&am…...

nas-群晖docker查询注册表失败解决办法(平替:使用SSH命令拉取ddns-go)
目录 前言必读 一、遇到问题 二、操作步骤 (一)打开群晖系统的SSH服务? (二)Windows电脑本地下载安装putty? 输入登录账号密码 开启root权限 例子:使用命令行下载ddns-go? 前言必读 读者手册(必…...
GSMA SGP.31 eSIM IoT 架构与需求笔记
GSMA SGP.31 eSIM IoT 架构与需求笔记 (版本 1.2,2024 年 4 月 26 日) 一、 概述 1. 文档目的: 本文件旨在为网络受限和/或用户界面 (UI) 受限的物联网 (IoT) 设备中的嵌入式通用集成电路卡 (eUICC) 提供远程配置架构和需求规范。 2. 主要内容&#…...
sql版本序列号
SQL Server 2019 Enterprise密钥:HMWJ3-KY3J2-NMVD7-KG4JR-X2G8G SQL Server 2019 Enterprise Core密钥:2C9JR-K3RNG-QD4M4-JQ2HR-8468J SQL Server 2019 Standard密钥:PMBDC-FXVM3-T777P-N4FY8-PKFF4 SQL Server 2019 Web密钥:33…...
vue2-nextTick
这里是引用 vue2-nextTick 1. 什么是nextTick 先来看官方定义 在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM云里雾里,啥意思呢,其实本质就是事件循环、同步和异步的问题不懂事件循环相关问题的…...

【其他专题】如何在线将PNG转ICO图标
在我们编程打包成exe时,可能需要一些图标文件。但往往我们下载的图标文件是.png或是其他格式的,是不能用于做图标文件的,因为图标文件往往是.ico文件。 比如下图所示的.png文件,我们怎么快速的将它转为ico文件呢? 首先…...

2019_AutoInt
AutoInt:通过自注意神经网络进行自动特征交互学习 创新点复现论文0摘要1介绍2相关工作2.1点击率预测2.2学习特征交互2.3注意力和残差网络 3问题定义4自动特征交互学习4.1概述4.2输入层4.3嵌入层4.4交互层4.5输出层 4.6训练4.7 AutoInt分析 5实验5.1实验装置5.2定量结…...

HAL库 Systick定时器 基于STM32F103EZT6 野火霸道,可做参考
目录 1.时钟选择(这里选择高速外部时钟) 编辑 2.调试模式和时基源选择: 3.LED的GPIO配置 这里用板子的红灯PB5 4.工程配置 5.1ms的systick中断实现led闪烁 源码: 6.修改systick的中断频率 7.systick定时原理 SysTick 定时器的工作原理 中断触发机制 HAL_SYSTICK_Co…...
使用 Postman 进行 API 测试:从入门到精通
使用 Postman 进行 API 测试:从入门到精通 使用 Postman 进行 API 测试:从入门到精通一、什么是 API 测试?二、Postman 简介三、环境搭建四、API 测试流程1. 收集 API 文档2. 发送基本请求示例:发送 GET 请求示例代码(…...

K8s 分布式存储后端(K8s Distributed Storage Backend)
K8s 分布式存储后端 在 K8s 中实现分布式存储后端对于管理跨集群的持久数据、确保高可用性、可扩展性和可靠性至关重要。在 K8s 环境中,应用程序通常被容器化并跨多个节点部署。虽然 K8s 可以有效处理无状态应用程序,但有状态应用程序需要持久存储来维护…...

基于docker搭建Kafka集群,使用KRaft方式搭建,摒弃Zookeeper
KAFKA基于docker使用KRaft进行集群搭建 环境:已成功搭建kafka服务 可点击链接跳转至安装kafka-3.8.0版本 并启用SASL认证 教程 使用基于Zookeeper方式搭建集群教程 kafka-3.8.0版本 并启用SASL认证 教程 搭建kafka-ui可视化工具 192.168.2.91 192.168.2.92 192…...
Centos7 安装 RabbitMQ与Erlang
1、下载erlang和rabbitmq wget https://github.com/rabbitmq/erlang-rpm/releases/download/v23.3.4.5/erlang-23.3.4.5-1.el7.x86_64.rpmwget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.16/rabbitmq-server-3.9.16-1.el7.noarch.rpm2、安装erlang…...
mybatis-plus的分页查询简单使用
引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version></dependency>在yml中配置启动mybatis-plus插件 mybatis-plus:configuration:#…...
剑指 Offer II 014. 字符串中的变位词
comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20014.%20%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E5%8F%98%E4%BD%8D%E8%AF%8D/README.md 剑指 Offer II 014. 字符串中的变位词 题目描述 给定两个字符…...

富唯智能复合机器人拓展工业新维度
富唯智能复合机器人是富唯智能倾力打造的一款集高度自动化、智能化和多功能性于一体的机器人。它融合了机械、电子、计算机、传感器等多个领域的前沿技术,通过精密的算法和控制系统,实现了对复杂生产环境的快速适应和高效作业。 富唯智能复合机器人的特点…...
【大数据技术】搭建完全分布式高可用大数据集群(Scala+Spark)
搭建完全分布式高可用大数据集群(Scala+Spark) scala-2.13.16.tgzspark-3.5.4-bin-without-hadoop.tgz注:请在阅读本篇文章前,将以上资源下载下来。 写在前面 本文主要介绍搭建完全分布式高可用集群Spark的详细步骤。 注意: 统一约定将软件安装包存放于虚拟机的/softwa…...
solidity高阶 -- 调用接口合约
在区块链开发中,Solidity 是一种广泛使用的智能合约编程语言,而接口合约(Interface)是 Solidity 中一个非常重要的概念。它为智能合约之间的交互提供了一种标准化的方式,使得合约之间的调用更加灵活、安全且易于管理。…...

若依框架使用(低级)
克隆源码 浏览器搜索若依,选择 RuoYi-Vue RuoYi-Vue RuoYi-Vue 重要的事情说三遍,进入gitee 下面这个页面(注意红色框起来的部分) 进入Gitee进行下载 我下载的是最新的springboot3 下载好后我们可以选择一个文件夹࿰…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...