c/c++开发中经常要用到http/https协议,直接使用socket工作量很大,要是使用socket实现https,那更不可思议,开源的c/c++的http客户端框架,libcurl是首选,而且也相当成熟稳定,最近C++项目中用到https请求,就做下研究。

libcurl简介(来源官网)

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

实现HTTP/GET:

Get.cpp

  1. /********************************************************
  2. Copyright (C), 2016-2018,
  3. FileName: Get
  4. Author: woniu201
  5. Email: wangpengfei.201@163.com
  6. Created: 2018/10/15
  7. Description: 实现HTTP/HTTPS GET请求
  8. ********************************************************/
  9. #include "main.h"
  10.  
  11. size_t WriteGetResp(void *buffer, size_t size, size_t nmemb, void *userp)
  12. {
  13. ((string*)userp)->append((char*)buffer, , size*nmemb);
  14. return size*nmemb;
  15. }
  16.  
  17. /************************************
  18. @ Brief: GET请求
  19. @ Author: woniu201
  20. @ Created: 2018/10/15
  21. @ Return:
  22. ************************************/
  23. int HttpGet(char* url)
  24. {
  25. string respData;
  26. CURL* curl;
  27. CURLcode res;
  28.  
  29. curl = curl_easy_init();
  30. if (curl == NULL)
  31. {
  32. return ;
  33. }
  34.  
  35. curl_easy_setopt(curl, CURLOPT_URL, url);
  36. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteGetResp);
  37. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respData);
  38.  
  39. // curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 5000); //libcurl存在毫秒超时bug,如果设备小于1000ms立即返回失败
  40. // curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000); //设置超时时间
  41.  
  42. bool bCA = FALSE;
  43. if (!bCA)
  44. {
  45. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);//设定为不验证证书和HOST
  46. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE);
  47. }
  48. else
  49. {
  50. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE);
  51. curl_easy_setopt(curl, CURLOPT_CAINFO, "");
  52. }
  53.  
  54. res = curl_easy_perform(curl);
  55. if (res != CURLE_OK)
  56. {
  57. cout << curl_easy_strerror(res) << endl;
  58. }
  59.  
  60. curl_easy_cleanup(curl);
  61.  
  62. cout << Utf8ToAscii(respData) << endl;
  63. return ;
  64. }

实现HTTP/POST:

Post.cpp

  1. /********************************************************
  2. Copyright (C), 2016-2018,
  3. FileName: Post
  4. Author: woniu201
  5. Email: wangpengfei.201@163.com
  6. Created: 2018/10/15
  7. Description: 实现HTTP/HTTPS POST请求
  8. ********************************************************/
  9. #include "main.h"
  10.  
  11. size_t WritePostBodyResp(void *buffer, size_t size, size_t nmemb, void *userp)
  12. {
  13. ((string*)userp)->append((char*)buffer, , size*nmemb);
  14. return size*nmemb;
  15. }
  16.  
  17. size_t WritePostHeaderResp(void *buffer, size_t size, size_t nmemb, void *userp)
  18. {
  19. ((string*)userp)->append((char*)buffer, , size*nmemb);
  20. return size*nmemb;
  21. }
  22.  
  23. /************************************
  24. @ Brief: POST请求
  25. @ Author: woniu201
  26. @ Created: 2018/10/15
  27. @ Return:
  28. ************************************/
  29. int HttpPost(char* url, char* body)
  30. {
  31. string respBodyData;
  32. string respHeadData;
  33. CURL* curl;
  34. CURLcode res;
  35.  
  36. //设置头
  37. struct curl_slist *headers = NULL;
  38. headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8");
  39.  
  40. curl = curl_easy_init();
  41. if (curl == NULL)
  42. {
  43. return ;
  44. }
  45.  
  46. curl_easy_setopt(curl, CURLOPT_URL, url);
  47. curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
  48. curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  49.  
  50. curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, WritePostHeaderResp);
  51. curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WritePostBodyResp);
  52. curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &respHeadData);
  53. curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respBodyData);
  54.  
  55. // curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 5000); //libcurl存在毫秒超时bug,如果设备小于1000ms立即返回失败
  56. // curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000); //设置超时时间
  57.  
  58. bool bCA = FALSE;
  59. if (!bCA)
  60. {
  61. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);//设定为不验证证书和HOST
  62. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE);
  63. }
  64. else
  65. {
  66. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE);
  67. curl_easy_setopt(curl, CURLOPT_CAINFO, "");
  68. }
  69.  
  70. res = curl_easy_perform(curl);
  71. if (res != CURLE_OK)
  72. {
  73. cout << curl_easy_strerror(res) << endl;
  74. }
  75. curl_slist_free_all(headers);
  76. curl_easy_cleanup(curl);
  77.  
  78. cout << Utf8ToAscii(respHeadData) << endl;
  79. cout << Utf8ToAscii(respBodyData) << endl;
  80.  
  81. return ;
  82. }

其他代码:

  1. utils.cpp
  1. /********************************************************
  2. Copyright (C), 2016-2018,
  3. FileName: utils
  4. Author: woniu201
  5. Email: wangpengfei.201@163.com
  6. Created: 2018/10/15
  7. Description: ASSIC--UTF8互转
  8. ********************************************************/
  9. #include "main.h"
  10. #include <string>
  11. #include <Windows.h>
  12. #include <wchar.h>
  13. using namespace std;
  14.  
  15. wstring AsciiToUnicode(const string& str) {
  16. // 预算-缓冲区中宽字节的长度
  17. int unicodeLen = MultiByteToWideChar(CP_ACP, , str.c_str(), -, nullptr, );
  18. // 给指向缓冲区的指针变量分配内存
  19. wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);
  20. // 开始向缓冲区转换字节
  21. MultiByteToWideChar(CP_ACP, , str.c_str(), -, pUnicode, unicodeLen);
  22. wstring ret_str = pUnicode;
  23. free(pUnicode);
  24. return ret_str;
  25. }
  26. string UnicodeToAscii(const wstring& wstr) {
  27. // 预算-缓冲区中多字节的长度
  28. int ansiiLen = WideCharToMultiByte(CP_ACP, , wstr.c_str(), -, nullptr, , nullptr, nullptr);
  29. // 给指向缓冲区的指针变量分配内存
  30. char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);
  31. // 开始向缓冲区转换字节
  32. WideCharToMultiByte(CP_ACP, , wstr.c_str(), -, pAssii, ansiiLen, nullptr, nullptr);
  33. string ret_str = pAssii;
  34. free(pAssii);
  35. return ret_str;
  36. }
  37.  
  38. wstring Utf8ToUnicode(const string& str) {
  39. // 预算-缓冲区中宽字节的长度
  40. int unicodeLen = MultiByteToWideChar(CP_UTF8, , str.c_str(), -, nullptr, );
  41. // 给指向缓冲区的指针变量分配内存
  42. wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);
  43. // 开始向缓冲区转换字节
  44. MultiByteToWideChar(CP_UTF8, , str.c_str(), -, pUnicode, unicodeLen);
  45. wstring ret_str = pUnicode;
  46. free(pUnicode);
  47. return ret_str;
  48. }
  49. string UnicodeToUtf8(const wstring& wstr) {
  50. // 预算-缓冲区中多字节的长度
  51. int ansiiLen = WideCharToMultiByte(CP_UTF8, , wstr.c_str(), -, nullptr, , nullptr, nullptr);
  52. // 给指向缓冲区的指针变量分配内存
  53. char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);
  54. // 开始向缓冲区转换字节
  55. WideCharToMultiByte(CP_UTF8, , wstr.c_str(), -, pAssii, ansiiLen, nullptr, nullptr);
  56. string ret_str = pAssii;
  57. free(pAssii);
  58. return ret_str;
  59. }
  60.  
  61. /************************************
  62. @ Brief: ASSIC转UTF8
  63. @ Author: woniu201
  64. @ Created: 2018/10/16
  65. @ Return:
  66. ************************************/
  67. string AsciiToUtf8(const string& str) {
  68. return UnicodeToUtf8(AsciiToUnicode(str));
  69. }
  70.  
  71. /************************************
  72. @ Brief: UTF8转ASSIC
  73. @ Author: woniu201
  74. @ Created: 2018/10/16
  75. @ Return:
  76. ************************************/
  77. string Utf8ToAscii(const string& str) {
  78. return UnicodeToAscii(Utf8ToUnicode(str));
  79. }
  1. #ifndef _MAIN_H
  2. #define _MAIN_H
  3.  
  4. #include <iostream>
  5. #include <string>
  6. #include "include/curl.h"
  7.  
  8. using namespace std;
  9.  
  10. #pragma comment(lib, "ssleay32.lib")
  11. #pragma comment(lib, "libcurl.lib")
  12.  
  13. string AsciiToUtf8(const string& str);
  14. string Utf8ToAscii(const string& str);
  15.  
  16. int HttpGet(char* url);
  17. int HttpPost(char* url, char* body);
  18. int HttpDownload(char* url, char* filePath);
  19. #endif

对应libcurl库和头文件下载地址(支持HTTPS):点击下载

扫码关注公众号

专注分享C/C++,C++(11,14,17),STL,Java,Spring,mybatis,mysql,redis,分布式,高并发,设计模式,爬虫,docker,shell编程等相关技术,还有高薪互联网职位内推,在这里一起探讨,一起学习,一起进步,同时不定期分享视频书籍资源,充分利用碎片化时间,让我们的技术之路更加有乐趣。

基于libcurl实现REST风格http/https的get和post的更多相关文章

  1. 基于MVC的RESTful风格的实现

    基于MVC的RESTful风格的实现 1.RESTful风格阐述 REST服务是一种ROA(Resource-Oriented Architecture,面向资源的架构)应用.主要特点是方法信息存在于 ...

  2. C++服务器开发之基于对象的编程风格

    Thread.h #ifndef _THREAD_H_ #define _THREAD_H_ #include <pthread.h> #include <boost/functio ...

  3. [解读REST] 4.基于网络应用的架构风格

    上篇文章介绍了一组自洽的术语来描述和解释软件架构:如何利用架构属性评估一个架构风格:以及对于基于网络的应用架构来说,那些架构属性是值得我们重点关注评估的.本篇在以上的基础上,列举一下一些常见的(RES ...

  4. 基于MVC的RESTFul风格API实战

    基于MVC的RESTful风格的实现 1.RESTful风格阐述 REST服务是一种ROA(Resource-Oriented Architecture,面向资源的架构)应用.主要特点是方法信息存在于 ...

  5. 基于阿里云上实现全站https的正确姿势(一)

    对应的网址:https://yq.aliyun.com/articles/65199 摘要: 目前主流大厂的网站和服务都已经实现了全站https, 例如: baidu, taobao, jd等. 关于 ...

  6. 基于libcurl的restfull接口 post posts get gets

    头文件 #pragma once #ifndef __HTTP_CURL_H__ #define __HTTP_CURL_H__ #include <string> #include &q ...

  7. 基于Nginx服务器和iOS9的HTTPS安全通信

    简介 在网络通信中,使用抓包软件可以对网络请求进行分析,并进行重放攻击,重放攻击的解决方案一般是使用一个变化的参数,例如RSA加密的时间戳,但考虑到网络传输时延,时间戳需要有一定的误差容限,这样仍然不 ...

  8. restfull 风格 参考 https://blog.csdn.net/jaryle/article/details/52141097

    https://www.cnblogs.com/xiaoxian1369/p/4332390.html :

  9. Prometheus基于consul自动发现监控对象 https://www.iloxp.com/archive/11/

      Prometheus 监控目标为什么要自动发现 频繁对Prometheus配置文件进行修改,无疑给运维人员带来很大的负担,还有可能直接变成一个“配置小王子”,即使是配置小王子也会存在人为失误的情况 ...

随机推荐

  1. handsontable-developer guide-cell function

    renderer 展示的数据不是来自于数据源,而是先把DOM和其他信息传给renderer,然后展示. //五种展示函数 TextRenderer: default NumericRenderer A ...

  2. [美国代购] Nexus 6 与 Moto X 询价聊天记录整理

    目前手上使用的是 Mi 3,使用了根本还不到一年,但是发现非常多的问题. 官方 APP 不能卸载: 手机的顶部(摄像头)处经常出现高温度现象,如果你长时间讲电话,那么这个温度真的可以烫到你的耳朵无法承 ...

  3. 注解Annotation补充介绍

    摘抄http://www.cnblogs.com/peida/archive/2013/04/23/3036035.html 什么是注解(Annotation): Annotation(注解)就是Ja ...

  4. Reverting back to the R12.1.1 and R12.1.3 Homepage Layout

    Reverting back to the 12.1.1 Homepage Layout Set the following profiles: FND: Applications Navigator ...

  5. nancy中的本地化

    1 建立一个文件夹 ,名称可以任意 2 添加资源文件 比如 Text.resx 3 使用 <h3>"@Text.Text.Greeting"</h3> 其中 ...

  6. [51单片机] nRF24L01 无线模块 串口法命令 通过无线控制另一个的灯

    >_<!概述: 这是在上一个的基础上通过按键发送4种不同命令来控制接收端的LED灯亮的改进版(上一个:http://www.cnblogs.com/zjutlitao/p/3840013. ...

  7. 安装、启动consul

    1.下载 从consul官网https://www.consul.io/downloads.html下载 2.解压.配置 将下载的  consul_1.4.4_linux_amd64.zip 解压 t ...

  8. Vue的基本认识与使用

    什么是Vue? Vue是一个渐进式的js框架,采用的是MVVM模式的双向绑定, Vue的使用 引入vue        <script src="vuejs/vue.js"& ...

  9. 3D-2D:PnP

    PnP(Perspective-n-Point):当知道n个3D空间点及其投影位置时,估计相机位姿. 2D-2D的对极几何方法需要八个或八个以上的点对(以八点法为例),且存在着初始化.纯旋转和尺度的问 ...

  10. [Scala随用随学] —— sealed声明的作用

    今天在看MLlib的源码时,看到Vector的声明是sealed trait,很好奇这个sealed有什么作用,与是搜到了这个文章: http://www.cnblogs.com/rollenholt ...