Chinaunix首页 | 论坛 | 博客
  • 博客访问: 553454
  • 博文数量: 127
  • 博客积分: 1169
  • 博客等级: 少尉
  • 技术积分: 1298
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-16 14:29
个人简介

空白

文章分类

全部博文(127)

分类: 嵌入式

2017-02-23 17:10:15

目的:使用libcurl与平台进行http通信,发送post和get请求。

1. 建立项目
建立包含如下内容的简单项目:

include: 包含libcurl头文件,将libcurl的头文件包含目录curl置于该include目录中;
lib: 将libcurl.a文件放入该目录下;
Makefile: 项目makefile文件;
MyCurl.h: libcurl接口封装声明文件;
MyCurl.cpp: libcurl接口封装实现文件;
main.cpp: main函数文件;

2. 代码编写
MyCurl.h内容如下:

  1. #ifndef NET_CURL_H
  2. #define NET_CURL_H

  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif

  6. #define SERV_REQ_LEN        64
  7. #define SERV_URL_LEN        256
  8. #define SERV_DOMAIN_LEN        64
  9. #define SERV_HOST_LEN        16
  10. #define SERV_RANGE_LEN        32

  11. /* 平台POST请求URL数据 */
  12. typedef struct PlatformPostUrl
  13. {
  14.     char servReq[SERV_REQ_LEN]; /* 请求名称 */
  15.     char servUrl[SERV_URL_LEN]; /* 保存URL */
  16.     char servDomain[SERV_DOMAIN_LEN]; /* HTTP头HOST字段值 */
  17.     char servHost[SERV_HOST_LEN]; /* 服务器IP地址 */
  18.     int servPort;      /* 服务器端口 */
  19.     char *data;      /* 数据 */
  20.     
  21. } PLATFORM_POST_URL;

  22. /* 平台GET请求URL数据 */
  23. typedef struct PlatformGetUrl
  24. {
  25.     int offset;          /* 下载文件偏移,用于断点下载升级文件 */
  26.     int flushSize;
  27.     char servUrl[SERV_URL_LEN]; /* 文件下载地址 */
  28.     char servDomain[SERV_DOMAIN_LEN]; /* 文件下载域名 */
  29.     char range[SERV_RANGE_LEN]; /* 下载文件内容范围 */
  30.     FILE *fp;      /* 文件保存文件指针 */
  31.     
  32. } PLATFORM_GET_URL;

  33. typedef size_t (*PARSE_FUN)(void *, size_t , size_t , void *);

  34. int CurlHttpPost(PLATFORM_POST_URL *url, PARSE_FUN parseFun, void *arg);

  35. int CurlHttpGet(PLATFORM_GET_URL *url, PARSE_FUN parseFun);

  36. void CurlPrintRspMsg(char *data, size_t dataLen);

  37. int CurlInit();

  38. void CurlDeinit();

  39. #ifdef __cplusplus
  40. }
  41. #endif

  42. #endif //NET_CURL_H
MyCurl.cpp内容如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>

  4. #include "curl.h"
  5. #include "MyCurl.h"

  6. #ifndef TRACE_PRT
  7. #define TRACE_PRT printf
  8. #endif
  9. #define MAX_RSP_MSG_LEN        (2048)
  10. #define RET_FAILURE     (-1)
  11. #define RET_SUCCESS     (0)
  12. #define POST_OPT_TIMEOUT    (30L)
  13. #define POST_CON_TIMEOUT    (10L)
  14. #define GET_OPT_TIMEOUT        (600L)
  15. #define GET_CON_TIMEOUT        (30L)
  16. #define HTTP_USER_AGENT        "CURLDE/"
  17. static char g_acRspMsgBuff[MAX_RSP_MSG_LEN] = {0};

  18. int CurlInit()
  19. {
  20.     CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
  21.     if (code == CURLE_OK)
  22.         return RET_SUCCESS;
  23.     else
  24.         return RET_FAILURE;
  25. }

  26. char *CurlVersion()
  27. {
  28.     return curl_version();
  29. }

  30. void CurlDeinit()
  31. {
  32.     curl_global_cleanup();
  33. }

  34. static void CurlInitGetHead(CURL *curl, struct curl_slist *list, PLATFORM_GET_URL *url)
  35. {
  36.     return;
  37. }

  38. static void CurlInitPostHead(CURL *curl, struct curl_slist *list, PLATFORM_POST_URL *url)
  39. {
  40.     /* 修改content-Type */
  41.     list = curl_slist_append(list, "Content-Type: application/json");
  42.     /* 屏蔽Expect100-continue */
  43.     list = curl_slist_append(list, "Expect:");

  44.     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
  45. }

  46. void CurlPrintRspMsg(char *pMsgData, size_t uiDataLen)
  47. {
  48.     if (!pMsgData)
  49.         return;
  50.     
  51.     size_t uiTmpLen = uiDataLen;
  52.             
  53.     if (uiTmpLen > sizeof(g_acRspMsgBuff) - 1)
  54.     {
  55.         TRACE_PRT("warnning, recv data len(%u) too long.\r\n", uiTmpLen);
  56.         uiTmpLen = sizeof(g_acRspMsgBuff) - 1;
  57.     }
  58.     
  59.     char *token = strstr(pMsgData, "\r\n");
  60.     if (token != NULL)
  61.     {
  62.         uiTmpLen = token - pMsgData;
  63.         if (uiTmpLen > sizeof(g_acRspMsgBuff) - 1)
  64.             uiTmpLen = sizeof(g_acRspMsgBuff) - 1;
  65.     }

  66.     memset(g_acRspMsgBuff, 0, sizeof(g_acRspMsgBuff));
  67.     memcpy(g_acRspMsgBuff, pMsgData, uiTmpLen);
  68.     g_acRspMsgBuff[sizeof(g_acRspMsgBuff) - 1] = '\0';
  69.     
  70.     TRACE_PRT("%s\r\n", g_acRspMsgBuff);
  71. }

  72. int CurlHttpPost(PLATFORM_POST_URL *url, PARSE_FUN parseFun, void *arg)
  73. {
  74.     CURL *curl = NULL;
  75.     CURLcode res;
  76.     struct curl_slist *list = NULL;
  77.     
  78.     if (!url || !parseFun)
  79.     {
  80.         TRACE_PRT("ERROR, param is NULL\n");
  81.         return RET_FAILURE;
  82.     }
  83.     
  84.     curl = curl_easy_init();
  85.     if (curl == NULL)
  86.     {
  87.         TRACE_PRT("ERROR, http curl easy init FAIL\n");
  88.         return RET_FAILURE;
  89.     }

  90.     CurlInitPostHead(curl, list, url);
  91.     
  92.     curl_easy_setopt(curl, CURLOPT_URL, url->servUrl);    /* 设置请求url */
  93.     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, url->data);        /* 设置请求发送给服务器数据 */        
  94.     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, parseFun);        /* 服务器应答处理函数指针 */    
  95.     curl_easy_setopt(curl, CURLOPT_WRITEDATA, arg);        /* parseFun函数参数 */
  96.     curl_easy_setopt(curl, CURLOPT_POST, 1L);        /* 使用post请求 */    
  97.     curl_easy_setopt(curl, CURLOPT_TIMEOUT, POST_OPT_TIMEOUT); /* 整个请求处理的最大超时时间 */
  98.     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, POST_CON_TIMEOUT);    /* connect服务器的最大超时时间 */
  99. #ifdef CURL_DEBUG
  100.     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);        /* 调试开关 */
  101. #endif

  102.     res = curl_easy_perform(curl);
  103.     if (res != CURLE_OK)
  104.     {
  105.         TRACE_PRT("ERROR, http perform FAILED(%d:%s).\n", res, curl_easy_strerror(res));
  106.         curl_easy_cleanup(curl);
  107.         curl_slist_free_all(list); /* free the list again */
  108.         return RET_FAILURE;
  109.     }

  110.     curl_easy_cleanup(curl);
  111.     curl_slist_free_all(list); /* free the list again */
  112.     
  113.     return RET_SUCCESS;
  114. }

  115. int CurlHttpGet(PLATFORM_GET_URL *url, PARSE_FUN parseFun)
  116. {
  117.     CURL *curl = NULL;
  118.     CURLcode res;
  119.     struct curl_slist *list = NULL;
  120.     
  121.     if (!url || !parseFun)
  122.     {
  123.         TRACE_PRT("ERROR, param is NULL\n");
  124.         return -1;
  125.     }

  126.     curl = curl_easy_init();
  127.     if (curl == NULL)
  128.     {
  129.         TRACE_PRT("ERROR, curl_easy_init FAIL.\n");
  130.         return -1;
  131.     }

  132.     CurlInitGetHead(curl, list, url);

  133.     curl_easy_setopt(curl, CURLOPT_URL,         url->servUrl);
  134.     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,     parseFun);
  135.     curl_easy_setopt(curl, CURLOPT_WRITEDATA,         url);
  136.     curl_easy_setopt(curl, CURLOPT_RANGE,         url->range);                /* 下载文件的起始范围 */
  137.     //curl_easy_setopt(curl, CURLOPT_RESUME_FROM,     url->offset);          /* 从offset偏移开始下载文件 */
  138.     curl_easy_setopt(curl, CURLOPT_TIMEOUT,         GET_OPT_TIMEOUT);     /* 文件下载最长时间600s */
  139.     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT,     GET_CON_TIMEOUT);
  140.     
  141. #ifdef CURL_DEBUG
  142.     curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
  143. #endif

  144.     TRACE_PRT("connected to: %s.\n", url->servUrl);

  145.     res = curl_easy_perform(curl);
  146.     if (res != CURLE_OK)
  147.     {
  148.         TRACE_PRT("ERROR, http client perform FAILED: %d(%s).\n", res, curl_easy_strerror(res));
  149.         curl_easy_cleanup(curl);
  150.         curl_slist_free_all(list); /* free the list again */
  151.         return -1;
  152.     }

  153.     curl_easy_cleanup(curl);
  154.     curl_slist_free_all(list); /* free the list again */
  155.     
  156.     return 0;
  157. }
main.cpp内容如下:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>

  4. #include "MyCurl.h"

  5. #define TRACE_PRT printf
  6. #define Malloc malloc
  7. #define Free free
  8. #define MDL __FUNCTION__, __LINE__

  9. #define OTHER_DATA_LEN (512)
  10. #define PLATFORM_SERV_PORT (80)
  11. #define MAX_MSG_LEN (2048)
  12. #define PLATFORM_SERV_HOST "14.18.201.47"
  13. #define PLATFORM_SERV_NAME ""
  14. #define PLATFORM_SERV_URL "http://%s:%d/uid/%s"
  15. #define PLATFORM_REQ_HTML "20698826.html"

  16. static void InitPlatformUrl(PLATFORM_POST_URL *url, const char *servReq)
  17. {
  18.     memset(url->servReq, 0, sizeof(url->servReq));
  19.     strncpy(url->servReq, servReq, sizeof(url->servReq) - 1);

  20.     url->servPort = PLATFORM_SERV_PORT;
  21.     strncpy(url->servDomain, PLATFORM_SERV_NAME, sizeof(url->servDomain) - 1);
  22.     strncpy(url->servHost, PLATFORM_SERV_HOST, sizeof(url->servHost) - 1);
  23.     snprintf(url->servUrl, sizeof(url->servUrl) - 1,
  24.                         PLATFORM_SERV_URL,
  25.                         url->servDomain,
  26.                         url->servPort,
  27.                         url->servReq);

  28.     TRACE_PRT("%s\r\n", url->servUrl);
  29. }

  30. static size_t ParseResponseRequest(void *buffer, size_t size, size_t nmemb, void *stream)
  31. {
  32.     char *recvData = (char *)buffer;
  33.     
  34.     size_t dataSize = size * nmemb;
  35.     char *response = (char *)stream;
  36.     
  37.     if (dataSize <= 0)
  38.     {
  39.         return dataSize;
  40.     }

  41.     if (dataSize >= MAX_MSG_LEN - 1)
  42.         dataSize = MAX_MSG_LEN - 1;
  43.     
  44.     memcpy(response, recvData, dataSize);
  45.     
  46.     return dataSize;
  47. }

  48. static int DealCurlRequest(const char *reqName)
  49. {
  50.     int ret = -1;
  51.     PLATFORM_POST_URL url;
  52.     char *msgData = (char *)Malloc(sizeof(char) * MAX_MSG_LEN);
  53.     if (!msgData)
  54.     {
  55.         TRACE_PRT("Malloc memory FAIL.\n");
  56.         return -1;
  57.     }
  58.     memset(msgData, 0, MAX_MSG_LEN);
  59.     
  60.     memset(&url, 0, sizeof(url));
  61.     url.data = NULL;

  62.     InitPlatformUrl(&url, reqName);
  63.     
  64.     unsigned int dataLen = OTHER_DATA_LEN;
  65.     url.data = (char *)Malloc(dataLen);
  66.     if (!url.data)
  67.     {
  68.         TRACE_PRT("> ERROR, malloc FAIL. %s %d\r\n", MDL);
  69.         return -1;
  70.     }
  71.     
  72.     memset(url.data, 0, dataLen);
  73.     snprintf(url.data, dataLen - 1, "%s", "");

  74.     ret = CurlHttpPost(&url, ParseResponseRequest, msgData);
  75.     if (0 == ret)
  76.     {
  77.         ret = 0;
  78.     }
  79.     else
  80.     {
  81.         ret = -1;
  82.     }

  83.     if (0 == ret)
  84.     {
  85.         TRACE_PRT("response: %s\r\n", msgData);
  86.     }
  87.     
  88.     Free(url.data);
  89.     Free(msgData);
  90.     
  91.     return ret;
  92. }

  93. int main(int argc, char **argv)
  94. {
  95.     int ret = -1;

  96.     ret = CurlInit();
  97.     if (0 != ret)
  98.     {
  99.         TRACE_PRT("curl inti FAIL\n");
  100.         return -1;
  101.     }

  102.     ret = DealCurlRequest(PLATFORM_REQ_HTML);

  103.     CurlDeinit();

  104.     return ret;
  105. }
Makefile:
  1. TARGET = libcurl_demo

  2. CC=gcc
  3. CX=g++

  4. INCLUDE_CURL_DIR = ./include/curl
  5. LIBRARY_DIR += ./lib
  6. LIBRARY_FILE += $(LIBRARY_DIR)/libcurl.a
  7. LIBRARY_FILE += -lm
  8. LIBRARY_FILE += -lrt
  9. LIBRARY_FILE += -ldl

  10. OBJS = $(patsubst %.c, %.o, $(wildcard *.c))
  11. OBJS += $(patsubst %.cpp, %.o, $(wildcard *.cpp))

  12. CCFLAGS = -g -Wall -O2

  13. $(TARGET) : $(OBJS)    
  14.     $(CXX) $^ -o $@ $(CCFLAGS) -I$(INCLUDE_CURL_DIR) -L$(LIBRARY_DIR) $(LIBRARY_FILE)

  15. %.o : %.c    
  16.     $(CC) -c $< $(CCFLAGS) -I$(INCLUDE_CURL_DIR)

  17. %.o : %.cpp
  18.     $(CXX) -c $< $(CCFLAGS) -I$(INCLUDE_CURL_DIR)

  19. clean:    
  20.     rm *.o $(TARGET)

  21. .PHONY:clean
3. 编译
  1. root@sar:/code/mytest/libcurl_demo# make
  2. g++ -c main.cpp -g -Wall -O2 -I./include/curl
  3. g++ -c MyCurl.cpp -g -Wall -O2 -I./include/curl
  4. g++ main.o MyCurl.o -o libcurl_demo -g -Wall -O2 -I./include/curl -L./lib ./lib/libcurl.a -lm -lrt -ldl
4. 测试
  1. root@sar:/code/mytest/libcurl_demo# ./libcurl_demo
  2. http://www.baidu.com:80/uid/20698826.html
  3. response: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
  4. <html><head>
  5. <title>302 Found</title>
  6. </head><body>
  7. <h1>Found</h1>
  8. <p>The document has moved <a href="http:///search/error.html">here</a>.</p>
  9. </body></html>

  10. root@sar:/code/mytest/libcurl_demo#
阅读(1967) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~