Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2565362
  • 博文数量: 315
  • 博客积分: 3901
  • 博客等级: 少校
  • 技术积分: 3640
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-08 15:32
个人简介

知乎:https://www.zhihu.com/people/monkey.d.luffy Android高级开发交流群2: 752871516

文章分类

全部博文(315)

文章存档

2019年(2)

2018年(1)

2016年(7)

2015年(32)

2014年(39)

2013年(109)

2012年(81)

2011年(44)

分类: C/C++

2012-08-19 22:42:06

    工作一个星期了,基本都在看别人代码。现在主要看的是Http部分的,不断和服务器交互,不断得到反馈信息或者提交信息。诸如此类,因此为了加深C对Http的处理,还是稍微练习下或者说了解和实验下,俗话说“好记性不如烂笔头”,厉害的人都是靠学习来的。
   在Windows下利用C语言进行http请求,向google天气API发送请求获取数据并保存!以下是工程文件:
各个文件代码:

点击(此处)折叠或打开

  1. //> downdata.h

  2. #ifndef DOWNDATA_H_INCLUDED
  3. #define DOWNDATA_H_INCLUDED

  4. #define BUFFSIZE_H 1024

  5. #ifdef __cpluscplus
  6. extern "C"
  7. {
  8. #endif

  9. /**
  10. * @brief 向网络请求资源,返回值存储到当前目录的临时文件whether.txt中.
  11. * @param pUrl[in] - 请求的URL.
  12. * @return if get data return true, else if get nothing return false.
  13. */
  14. bool WEBQuest(const char * pUrl);

  15. #ifdef __cpluscplus
  16. }
  17. #endif

  18. #endif // DOWNDATA_H_INCLUDED

  19. //> downdata.cpp
  20.   
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. //#include "windows.h"
  25. #include "winsock2.h"

  26. #include "downdata.h"
  27. #include "freeptr.h"

  28. #pragma comment(lib, "ws2_32.lib") //在某些编译器下,需要添加编译参数到工程设置中,比如CodeBlocks(这样,这行就不需要了).
  29.                                                                       //Code::blocks 中新建一个工程, 然后右击工程
  30.                                                                       //选择 build options -> Linker setting
  31.                                                                       //在Other linker options 中添加: -lwsock32
  32. /**
  33. * @brief 为了加深http的理解和数据相关的操作,实现之.
  34. */
  35. bool WEBQuest(const char * pUrl)
  36. {
  37. #if 1 //no this declaration, socket create failed.
  38.     WSADATA WsaData;

  39.     if (WSAStartup(MAKEWORD(2,2),&WsaData))
  40.     {
  41.         printf("The socket failed");
  42.         return false;
  43.     }
  44. #endif

  45.     SOCKET sockeId;
  46.     SOCKADDR_IN addr;

  47.     if (-1 == (sockeId = socket(AF_INET, SOCK_STREAM, 0)))
  48.     {
  49.         printf("socket create failed\n");
  50.         return false;
  51.     }

  52.     /// < dest_addr
  53.     addr.sin_addr.S_un.S_addr = inet_addr("74.125.71.105"); /// < googleIP,可以用IP地址查询得到
  54.     addr.sin_family = AF_INET;
  55.     addr.sin_port = htons(80);

  56.     /// < 分离url中的主机地址和相对路径 考虑到内存和性能,下面不是好习惯!
  57.     char *phost = 0;
  58.     char * myurl = (char * ) malloc (BUFFSIZE_H * sizeof(char));
  59.     char * host = (char * ) malloc (BUFFSIZE_H * sizeof(char));
  60.     char * GET = (char * ) malloc (BUFFSIZE_H * sizeof(char));
  61.     char * head =(char * ) malloc(BUFFSIZE_H * sizeof(char));
  62.     memset(myurl, '\0', BUFFSIZE_H);
  63.     memset(host, '\0', BUFFSIZE_H);
  64.     memset(GET, '\0', BUFFSIZE_H);
  65.     memset(head, '\0', BUFFSIZE_H);

  66.     /// < pUrl - www.google.com/ig/api?hl=zh_cn&weather=beijing
  67.     /// < www.google.com - &host
  68.     /// < /ig/api?hl=zh_cn&weather=beijing - &GET
  69.     strcpy(myurl, pUrl);

  70.     for (phost = myurl; *phost != '/' && *phost != '\0'; ++phost);
  71.     if ( (int)(phost - myurl) == strlen(myurl) )
  72.         strcpy(GET, "/");
  73.     else
  74.         strcpy(GET, phost);
  75.     *phost = '\0'; /// < 相当于在www.google.com//位置替换为'\0'.
  76.     strcpy(host, myurl); /// < 在www.google.com//位置为'\0',因此www.google.com被拷贝到&host.
  77.     printf("%s\n%s\n", host, GET);

  78.     /**
  79.     * 组织发送到web服务器的信息
  80.     * 为何要发送下面的信息connect请参考HTTP协议的约定
  81.     */
  82.     strcat(head, "GET ");
  83.     strcat(head, GET);
  84.     strcat(head, " HTTP/1.1\r\n");
  85.     strcat(head, "host: ");
  86.     strcat(head, host);
  87.     strcat(head, "\r\nConnection: Close\r\n\r\n");
  88.     printf(head);

  89.     if (SOCKET_ERROR == connect(sockeId, (SOCKADDR * )&addr, sizeof(addr)))
  90.     {
  91.         printf("connect failed!\n");
  92.         closesocket(sockeId);
  93.         WSACleanup();
  94. #if 0
  95.         free(myurl);
  96.         free(host);
  97.         free(GET);
  98.         free(head);
  99.         myurl = NULL;
  100.         host = NULL;
  101.         GET = NULL;
  102.         head = NULL;
  103. #endif
  104.         freeCharPtr(&myurl, &host, &GET, &head, NULL);

  105.         return false;
  106.     }

  107.     if (SOCKET_ERROR == send(sockeId, head, strlen(head), 0))
  108.     {
  109.         printf("send &header error!\n");
  110.         closesocket(sockeId);
  111.         WSACleanup();
  112. #if 0
  113.         free(myurl);
  114.         free(host);
  115.         free(GET);
  116.         free(head);
  117.         myurl = NULL;
  118.         host = NULL;
  119.         GET = NULL;
  120.         head = NULL;
  121. #endif
  122.           freeCharPtr(&myurl, &host, &GET, &head, NULL);

  123.         return false;
  124.     }

  125.     memset(head, '\0', BUFFSIZE_H);
  126.     FILE *fp;
  127.     fp = fopen("whether.xml", "w+");
  128.     if (NULL == fp)
  129.     {
  130.         printf("whether file create failed!\n");
  131.         closesocket(sockeId);
  132.         WSACleanup();
  133. #if 0
  134.         free(myurl);
  135.         free(host);
  136.         free(GET);
  137.         free(head);
  138.         myurl = NULL;
  139.         host = NULL;
  140.         GET = NULL;
  141.         head = NULL;
  142. #endif
  143.         freeCharPtr(&myurl, &host, &GET, &head, NULL);

  144.         return false;
  145.     }
  146.     while (recv(sockeId, head, BUFFSIZE_H, 0) > 0)
  147.     {
  148.         fputs(head, fp);
  149.         memset(head, '\0', BUFFSIZE_H);
  150.     }
  151. #if 0
  152.     free(myurl);
  153.     free(host);
  154.     free(GET);
  155.     free(head);
  156.     myurl = NULL;
  157.     host = NULL;
  158.     GET = NULL;
  159.     head = NULL;
  160. #endif
  161.     freeCharPtr(&myurl, &host, &GET, &head, NULL);
  162.     closesocket(sockeId);
  163.     WSACleanup();

  164.     return true;
  165. }

  166. /// < main.cpp
  167. #include <iostream> /// < system()
  168. #include <stdio.h>
  169. #include "downdata.h"
  170. using namespace std;

  171. int main(void )
  172. {
  173.     if (!WEBQuest("" ))
  174.     {
  175.         return -1;
  176.     }
  177.     printf( "Whether have been writtend to file whether.xml\n" );

  178.     system( "pause");
  179.     return 0;
  180. }

  181. //> 关于内存释放,自己封装了一个变参形式的(char **参数)释放函数
  182. //> freeptr.h

  183. #ifndef FREEPTR_H
  184. #define FREEPTR_H

  185. #ifdef __cpluscplus
  186. extern "C"
  187. {
  188. #endif

  189. /**
  190. * @brief 变参形式内存释放
  191. * param[in] ch - 字符指针
  192. * param[in] ... - 其他字符指针
  193. * 接口使用规范:
  194. *
  195. */
  196. void freeCharPtr(char ** ch, ...);

  197. #ifdef __cpluscplus
  198. }
  199. #endif
  200. #endif

  201. //> freeptr.cpp

  202. #include <stdlib.h>
  203. #include <stdarg.h>
  204. #include "freeptr.h"

  205. /**
  206. * @brief 变参形式内存释放
  207. */
  208. void freeCharPtr(char ** ch, ...)
  209. {
  210.           va_list ap;
  211.           char ** p;
  212.           
  213.           va_start(ap, ch);
  214.           free(*ch);
  215.           *ch = NULL;
  216.           while (p = va_arg(ap, char ** ))
  217.           {
  218.                   free(*p);
  219.                   *p = NULL;
  220.           }
  221. }

阅读(13172) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~