windows平台下 c/c++进行http通信的教训
来源:互联网 发布:网络测试好学吗 编辑:程序博客网 时间:2024/06/05 01:52
由于需要使用c++开发一个桌面应用软件,需要用到http请求进行通讯,也是本人第一次进行网络相关的开发工作,遇到了不少坑。
由于是在windows下开发和使用的应用软件,自然而然想到了调用Windows自带的sdk进行开发,开始就使用了winnet这个库,直接调用其AP,当把通讯接口的接口都开发完毕进行集成的时候,才发现winnet这个库是基于MFC框架的,这样子图形界面也需要基于MFC框架进行设计。但是项目中的UI是使用dui进行设计的,这样dui和MFC就出现的冲突,导致开发的通讯接口和UI无法集成。只要推倒重来,使用开源的库来开发通讯接口。
经过调研,发现libcurl这个库功能很齐全、可以满足开发的需求。libcurl的介绍可以到官网查看,有详细的文档和使用示例供学习者学习,比使用winnet的API接口方便多了。
使用libcurl也是简单明了,主要可以分为4个基本:
- 声明并初始化一个CURL句柄:
CURL *curl=curl = curl_easy_init();
- 设置句柄参数,包括URL地址、数据头等:
调用curl_easy_setopt函数,需要设置的参数为CURL句柄,参数名称,参数内容
格式为:curl_easy_setopt(handle, PARAM, paramData);
如设置URL: curl_easy_setopt(handle, CURLOPT_URL, "http://www.csdn.net/");
- 进行数据发送及接受:
CURLcode res=curl_easy_perform(curl);
- 进行句柄的清理工作,主要是断开链接并清理相关内存资源:
curl_easy_cleanup(curl);
其中最关键的是第二步,句柄参数的设置,和winnet最大的不同是发送数据和接受数据的传入及获取的问题,在winnet中,是通过由用户申请和开辟内存,把需要发送的数据的指针直接作为其API的参数,winnet接受数据时,则是先由用户判断接收数据的大小,再有用户开辟内存并在指针作为其API的参数,用起来不是太方便。而对于CURL来说,则是通过回调函数来实现读数据和写入数据的,更加的精简和易用。
完整的发送GET请求的过程如下实例:
</pre><pre name="code" class="cpp">char*CURL = "www....";char*sPort = "8080";CURL*curl_handle;/*声明一个CURL句柄*/CURLcoderes;/*声明一个状态变量*/struct MemoryStruct chunk;/*用来存放返回的参数*/chunk.memory = (char*)malloc(1);chunk.size = 0;struct curl_slist *headers = NULL;headers = curl_slist_append(headers,"Content-Type:application/json;charset = UTF-8");/*定义参数的格式为json*/res = curl_global_init(CURL_GLOBAL_ALL);if(CURLE_OK != res){returnNULL;}/*initthecurlsession*/curl_handle = curl_easy_init();if(NULL = = curl_handle){returnNULL;}curl_easy_reset(curl_handle);/*设置URL地址*/curl_easy_setopt(curl_handle,CURLOPT_URL,URL);/*设置为GET方法*/curl_easy_setopt(curl_handle,CURLOPT_HTTPGET,1);/*链接超时时间5秒**/curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT,5L);/*设置端口*///curl_easy_setopt(curl_handle,CURLOPT_PORT,sPort);/*包含协议头*///curl_easy_setopt(curl_handle,CURLOPT_HEADER,1);/*设置回调函数*/curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback);/*通过回调函数把请求获得的数据写入chunk*/curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,(void*)&chunk);curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"libcurl-agent/1.0");/*进行请求操作*/res = curl_easy_perform(curl_handle);/*进行资源释放*/curl_easy_cleanup(curl_handle);/*检查是否请求成功*/if(res != CURLE_OK){return NULL;}return chunk.memory;/*返回获得的参数*/
回调函数的实现:
struct MemoryStruct { char *memory; size_t size;}; static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp){ size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct MemoryStruct *)userp; mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1); if(mem->memory == NULL) { /* out of memory! */ LOG("crulHttp.cpp not enough memory (realloc returned NULL)"); return 0; } memcpy(&(mem->memory[mem->size]), contents, realsize); mem->size += realsize; mem->memory[mem->size] = 0; return realsize;}
另外,如果请求的URL中含有中文等字符,则需要对URL进行编码,libcurl也提供了专门的API供大家使用:
char *curlEncode(char*input){CURL *curl = curl_easy_init();if(curl) {char *output = curl_easy_escape(curl, input, 0);return output;}return NULL;}
最终的开发也是绕了一大圈,主要还是缺少网络开发这方面的认识和经验。
1 0
- windows平台下 c/c++进行http通信的教训
- windows平台下用eclispe进行c/c++开发
- windows平台下用eclispe进行c/c++开发
- Windows平台下搭建Obcject-C平台
- Windows平台进行Objective-C开发
- Windows平台进行Objective-C开发
- .net平台下C#socket通信
- windows下用c实现Socket通信
- Windows平台下Mysql C程序设计
- windows平台c语言使用socket通信传送图片
- 关于C结构体bit field的跨平台的教训
- 关于C结构体bit field的跨平台的教训
- Linux平台基于C编写的文本通信平台
- .net平台下C#socket通信(中)
- .net平台下C#socket通信(中)
- .net平台下C#socket通信(中)
- .net平台下C#socket通信(中)
- .net平台下C#socket通信(中)
- bzoj3876【Ahoi2014】支线剧情
- hadoop namenode ha--手动切换
- Android圆形头像
- SQL语句,聚集函和数据分组,接上文
- 尼科彻斯定理
- windows平台下 c/c++进行http通信的教训
- 黑马程序员——网络编程
- MinGW 是什么?
- 打包混淆初体验
- JVM飙高排查脚本-结构分析
- dp,px,pt,sp 的区别 以及dp 和 px 互转
- HDOJ 2009 求数列的和
- SQL语句,多表查询,连接查询,嵌套查询,集合操作,有IN谓词,有比较运算符,有ANY\EXIST谓词的查询
- maven依赖