一.  HTTP请求的数据流总结
#上传数据, yeelink的数据流如下
POST /v1.0/device/4420/sensor/9089/datapoints HTTP/1.1
Host: api.yeelink.net
U-ApiKey: 729d1ba15b26b6a48f4807ef3f2f4df4
Content-Length: 49
Content-Type: application/x-www-form-urlencoded
Connection: Close

{"timestamp":"2013-07-23T06:04:15","value":21.9}

#上传数据, lewer50的数据流如下
POST /api/V1/gateway/UpdateSensors/01 HTTP/1.1
Host: www.lewei50.com
userkey: 36be8ff22f794f1e8a0bee3336eef237
Content-Length: 31
Content-Type: application/x-www-form-urlencoded
Connection: Close

[{"Name":"T1","Value":"24.02"}]

三. 代码如下, 公用的 http_clound.h

点击(此处)折叠或打开

  1. /*----------------------------------------------------------------------------------------------------
  2. 云端查询: http://www.yeelink.net/devices/4420, http://www.lewei50.com/u/g/2375
  3. #调用例程
  4. float current_temp = 24.02;
  5. yeelink_create_data(YEELINK_DEVICE_ID, YEELINK_SENSOR_ID, current_temp);
  6. lewei50_create_data(LEWEI50_DEVICE_ID, current_temp);
  7. linux下三种方法和云端通讯:
  8. 1. 纯利用linux的网络函数
  9. 2. 利用libcurl的发送和接收函数
  10. 3. 利用libcurl的回调机制
  11. #上传数据, yeelink的字符流如下
  12. POST /v1.0/device/4420/sensor/9089/datapoints HTTP/1.1
  13. Host: api.yeelink.net
  14. U-ApiKey: 729d1ba15b26b6a48f4807ef3f2f4df4
  15. Content-Length: 49
  16. Content-Type: application/x-www-form-urlencoded
  17. Connection: Close
  18. {"timestamp":"2013-07-23T06:04:15","value":21.9}
  19. #上传数据, lewer50的字符流如下
  20. POST /api/V1/gateway/UpdateSensors/01 HTTP/1.1
  21. Host: www.lewei50.com
  22. userkey: 36be8ff22f794f1e8a0bee3336eef237
  23. Content-Length: 31
  24. Content-Type: application/x-www-form-urlencoded
  25. Connection: Close
  26. [{"Name":"T1","Value":"24.02"}]
  27. lewei50 ret = {"Successful":true,"Message":"Warning: T1\u0027s frequency limit is 10s; "}
  28. V1.0 2013-11-5 初步实现了上面三种方法的Demo.
  29. 错误: bfe06000-bfe1b000 rw-p 00000000 00:00 0 [stack], 修改: char pc_ret[200] -> char pc_ret[500]
  30. -----------------------------------------------------------------------------------------------------*/
  31. #ifndef HTTP_CLOUD_H
  32. #define HTTP_CLOUD_H
  33. //有replace的地方换成自己的参数
  34. #define YEELINK (1)    //www.yeelink.net
  35. #define LEWEI50 (1)    //www.lewei50.com
  36. #if (YEELINK == 1)
  37. #define YEELINK_URL            "http://api.yeelink.net"
  38. #define YEELINK_HOST        "api.yeelink.net"        //网址, 由此获得公网IP
  39. #define YEELINK_PORT        80
  40. #define YEELINK_API_KEY "729d1ba15b26b6a48f4807ef3f2f4df4" //replace your yeelink api key here.
  41. #define YEELINK_DEVICE_ID                4420 //replace your device ID
  42. #define YEELINK_SENSOR_ID                9089 //replace your sensor ID
  43. #endif
  44. #if (LEWEI50 == 1)
  45. #define LEWEI50_GATEWAY     01        //网关号
  46. #define LEWEI50_URL             "http://www.lewei50.com/api/V1/gateway/UpdateSensors/01"
  47. #define LEWEI50_HOST            "www.lewei50.com"        //网址, 由此获得公网IP
  48. #define LEWEI50_PORT            80
  49. #define LEWEI50_HOST_FILE    "api/V1/gateway/UpdateSensors/01"
  50. #define LEWEI50_USER_KEY     "36be8ff22f794f1e8a0bee3336eef237"    //replace your lewei50 key here.
  51. #define LEWEI50_DEVICE_ID "T1"                                                                //replace your device ID
  52. #endif
  53. #define DATA_CREATE     (0)    //创建数据点
  54. #define DATA_MODIFY     (1)    //修改数据点
  55. #define DATA_QUERY         (2)    //查询数据点
  56. #define HTTP_GET "GET"
  57. #define HTTP_PUT "PUT"
  58. #define HTTP_HEAD "HEAD"
  59. #define HTTP_POST "POST"
  60. #define HTTP_DELETE "DELETE"
  61. #define MAX_SEND_BUFFER_SIZE            (2 * 1024 * 1024)
  62. #define MAX_RECV_BUFFER_SIZE            (2 * 1024 * 1024)
  63. #define MAX_HEADER_BUFFER_SIZE        (128 * 1024)
  64. //http请求与接受的buffer总体结构
  65. //param_buffer_t中buffer的内容
  66. typedef struct {
  67. char *ptr; /**< 缓冲区首指针 */
  68. FILE *fp; /**< 文件指针 */
  69. unsigned int left; /** 缓冲区剩余大小 */
  70. unsigned int allocated; /** 缓冲区总大小 */
  71. unsigned short code; /**返回码 */
  72. } param_buffer_t;
  73. typedef struct {
  74. param_buffer_t *send_buffer; /**< send buffer */
  75. param_buffer_t *recv_buffer; /**< receive buffer */
  76. param_buffer_t *header_buffer; /**< header buffer */
  77. } curl_request_param_t;
  78. extern int yeelink_create_data(const int device_id, const int sensor_id, const float device_value);
  79. extern int lewei50_create_data(const char *device_id, const float device_value);
  80. #endif

纯利用linux的网络函数实现的代码如下

点击(此处)折叠或打开

  1. /*----------------------------------------------------------------------------------------------------
  2. 直接利用linux的内部函数实现云端通讯, 另外可以利用libcurl的API.
  3. -----------------------------------------------------------------------------------------------------*/
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <sys/types.h>
  8. #include <sys/socket.h>
  9. #include <errno.h>
  10. #include <unistd.h>
  11. #include <netinet/in.h>
  12. #include <limits.h>
  13. #include <netdb.h>
  14. #include <arpa/inet.h>
  15. #include <ctype.h>
  16. #include <time.h>
  17. #include <assert.h>
  18. #include "../http_cloud.h"
  19. #define DBG printf
  20. //-----------------------------------------------------------------------------------------
  21. static void get_local_time(char *pc_str)
  22. {
  23. time_t now;
  24. struct tm *timenow;
  25. assert(pc_str != NULL);
  26. time(&now);
  27. timenow = localtime(&now);
  28. sprintf(pc_str, "%04d-%02d-%02dT%02d:%02d:%02d", timenow->tm_year+1900, timenow->tm_mon+1, timenow->tm_mday,
  29. timenow->tm_hour, timenow->tm_min, timenow->tm_sec);
  30. }
  31. //连接云端: host_addr:网址(如api.yeelink.net), portno:端口号(一般为80), request: 完整的请求
  32. //返回参数: \r\n\r\n之后的数据, 一般为有效数据, 如{"Successful":true,"Message":"Successful. "}
  33. static char connect_cloud(char *pc_ret, const char *host_addr, const int portno, const char *request)
  34. {
  35. int sockfd = 0;
  36. char buffer[1024] = "";
  37. struct sockaddr_in server_addr;
  38. struct hostent *host;
  39. //int portno = 80;    //默认端口
  40. int nbytes = 0;
  41. //char host_addr[256] = "";
  42. //char host_file[1024] = "";
  43. char pc_tmp[1024] = "";
  44. int send = 0, totalsend = 0;
  45. int i = 0, iLen = 0, iRet = 0, iPos = 0, mark_num;
  46. assert((pc_ret != NULL) && (host_addr != NULL) && (request != NULL));
  47. //由host_addr取得主机IP地址
  48. if((host = gethostbyname(host_addr)) == NULL) {
  49. fprintf(stderr, "Gethostname error, %s\n ", strerror(errno));
  50. exit(1);
  51. }
  52. //客户程序开始建立sockfd描述符,建立SOCKET连接
  53. if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  54. fprintf(stderr, "Socket Error:%s\a\n ",strerror(errno));
  55. exit(1);
  56. }
  57. //客户程序填充服务端的资料
  58. bzero(&server_addr, sizeof(server_addr));
  59. server_addr.sin_family = AF_INET;
  60. server_addr.sin_port = htons(portno);
  61. server_addr.sin_addr = *((struct in_addr*)host->h_addr);
  62. //DBG("server_addr.sin_addr = %08X\n", server_addr.sin_addr);    //server_addr.sin_addr = CB3888CA
  63. //客户程序发起连接请求, 连接网站
  64. if(connect(sockfd, (struct sockaddr*)(&server_addr), sizeof(struct sockaddr)) == -1) {
  65. fprintf(stderr, "Connect Error:%s\a\n ",strerror(errno));
  66. exit(1);
  67. }
  68. //发送http请求request
  69. send = 0;
  70. totalsend = 0;
  71. nbytes = strlen(request);
  72. while(totalsend < nbytes)
  73. {
  74. send = write(sockfd, request+totalsend, nbytes-totalsend);
  75. if(send == -1) {
  76. DBG( "send error!%s\n ", strerror(errno));
  77. exit(0);
  78. }
  79. totalsend += send;
  80. //DBG("%d bytes send OK!\n ", totalsend);
  81. }
  82. //DBG( "\nThe following is the response header:\n");
  83. i = 0;
  84. mark_num = 4;        //正常=4,
  85. //连接成功了,接收http响应
  86. while((nbytes = read(sockfd, buffer, 1)) == 1)
  87. {
  88. //DBG("%c", buffer[0]);
  89. if(i < mark_num) {
  90. if(buffer[0] == '\r' || buffer[0] == '\n') {
  91. i++;
  92. //DBG("i = %d, ", i);
  93. if (iRet == 0) {
  94. pc_tmp[iPos] = '\0';
  95. if (!strcmp(pc_tmp, "HTTP/1.1 200 OK")) {
  96. iRet = 1;
  97. }
  98. }
  99. }
  100. else {
  101. i = 0;    //新行重新计数
  102. pc_tmp[iPos++] = buffer[0];
  103. }
  104. }
  105. else {
  106. pc_ret[iLen++] = buffer[0];    //获取有效数据
  107. }
  108. }
  109. close(sockfd);
  110. pc_ret[iLen] = '\0';
  111. DBG("\nret(%d): %s\n", iLen, pc_ret);
  112. return(iRet);
  113. }
  114. #if (YEELINK == 1)
  115. int yeelink_create_data(const int device_id, const int sensor_id, const float device_value)
  116. {
  117. char pc_ret[200], request[1024], pc_json[100], pc_time[30], pc_host_file[100], pc_header[100], ret;
  118. int len;
  119. sprintf(pc_host_file, "v1.0/device/%d/sensor/%d/datapoints", device_id, sensor_id);
  120. sprintf(pc_header, "U-ApiKey: %s", YEELINK_API_KEY);
  121. get_local_time(pc_time);
  122. sprintf(pc_json, "{\"timestamp\":\"%s\",\"value\":%.2f}", pc_time, device_value);
  123. len = strlen(pc_json);
  124. sprintf(request, "POST /%s HTTP/1.1\r\nHost: %s\r\nAccept: */*\r\n%s\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\nConnection: Close\r\n\r\n%s\r\n",
  125. pc_host_file, YEELINK_HOST, pc_header, len, pc_json);
  126. DBG("request = %s\n", request);
  127. ret = connect_cloud(pc_ret, YEELINK_HOST, YEELINK_PORT, request);
  128. return(ret);
  129. }
  130. #endif
  131. #if (LEWEI50 == 1)
  132. //curl --request POST http://www.lewei50.com/api/V1/Gateway/UpdateSensors/01 --data "[{\"Name\":\"T1\",\"Value\":\"23.08\"}]" --header "userkey:36be8ff22f794f1e8a0bee3336eef237"
  133. int lewei50_create_data(const char *device_id, const float device_value)
  134. {
  135. char pc_ret[200], request[1024], pc_json[100], pc_header[100], ret;
  136. int len;
  137. assert(device_id != NULL);
  138. sprintf(pc_header, "userkey: %s", LEWEI50_USER_KEY);
  139. sprintf(pc_json, "[{\"Name\":\"%s\",\"Value\":\"%.2f\"}]", device_id, device_value);
  140. len = strlen(pc_json);
  141. sprintf(request, "POST /%s HTTP/1.1\r\nHost: %s\r\nAccept: */*\r\n%s\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\nConnection: Close\r\n\r\n%s\r\n",
  142. LEWEI50_HOST_FILE, LEWEI50_HOST, pc_header, len, pc_json);
  143. DBG("request = %s\n", request);
  144. ret = connect_cloud(pc_ret, LEWEI50_HOST, LEWEI50_PORT, request);
  145. return(ret);
  146. }
  147. #endif
  148. //-------------------------------------------------------------------
  149. int main(void)
  150. {
  151. float f_value = 15.02;
  152. int i_tmp;
  153. time_t t;
  154. srand((unsigned)time(&t));    //初始化随机种子, 否则随机数不随机
  155. i_tmp = rand();
  156. i_tmp -= (i_tmp >> 4 << 4);
  157. f_value += i_tmp;
  158. #if (YEELINK == 1)
  159. yeelink_create_data(YEELINK_DEVICE_ID, YEELINK_SENSOR_ID, f_value);
  160. #endif
  161. #if (LEWEI50 == 1)
  162. lewei50_create_data(LEWEI50_DEVICE_ID, f_value);
  163. #endif
  164. return 1;
  165. }

四. 编译, Makefile如下,
OPENWRT = 0 时目标文件运行下ubuntu下了.

点击(此处)折叠或打开

  1. OPENWRT = 1
  2. ifeq ($(OPENWRT), 1)
  3. CC = ~/OpenWrt-SDK-ar71xx-for-linux-i486-gcc-4.6-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gcc
  4. CFLAGS += -I ~/openwrt-lib/include -L ~/openwrt-lib/lib
  5. else
  6. CC = gcc
  7. endif
  8. CFLAGS += -Wall -O2
  9. #CFLAGS += -g
  10. #可执行文件名和相关的obj文件
  11. APP_BINARY = http_cloud
  12. SRCS += http_cloud.c
  13. OBJS = $(SRCS:.c=.o)
  14. all: APP_FILE
  15. APP_FILE: $(OBJS)
  16. $(CC) $(CFLAGS) $(OBJS) -o $(APP_BINARY) $(LFLAGS)
  17. .PHONY: clean
  18. clean:
  19. @echo "cleanning project"
  20. $(RM) *.a $(OBJS) *~ *.so *.lo $(APP_BINARY)
  21. @echo "clean completed"

编译过程:
xxg@xxg-desktop:~/1-wire/http_cloud/linux_only$ make
gcc -Wall -O2   -c -o http_cloud.o http_cloud.c
gcc -Wall -O2 http_cloud.o -o http_cloud

运行结果:
xxg@xxg-desktop:~/1-wire/http_cloud/linux_only$ ./http_cloud
request = POST /v1.0/device/4420/sensor/9089/datapoints HTTP/1.1
Host: api.yeelink.net
Accept: */*
U-ApiKey: 729d1ba15b26b6a48f4807ef3f2f4df4
Content-Length: 49
Content-Type: application/x-www-form-urlencoded
Connection: Close

{"timestamp":"2013-11-05T14:32:48","value":16.02}

ret(5): 0

request = POST /api/V1/gateway/UpdateSensors/01 HTTP/1.1
Host: www.lewei50.com
Accept: */*
userkey: 36be8ff22f794f1e8a0bee3336eef237
Content-Length: 31
Content-Type: application/x-www-form-urlencoded
Connection: Close

[{"Name":"T1","Value":"16.02"}]

ret(44): {"Successful":true,"Message":"Successful. "}
xxg@xxg-desktop:~/1-wire/http_cloud/linux_only$

 

这个只是第一部分的实验, 后续的还有利用libcurl库的实现代码.

(转)linux下和云端通讯的例程, ubuntu和openwrt实验成功(一)的更多相关文章

  1. (转)linux下和云端通讯的例程, ubuntu和openwrt下实验成功(二)

    前言: 上节用纯linux的函数实现了和云端通讯, 本节开始利用传说中的神器libcurl 话说一个网络程序员对书法十分感兴趣,退休后决定在这方面有所建树. 于是花重金购买了上等的文房四宝.    一 ...

  2. (转)利用libcurl和国内著名的两个物联网云端通讯的例程, ubuntu和openwrt下调试成功(四)

    1. libcurl 的参考文档如下 CURLOPT_HEADERFUNCTION Pass a pointer to a function that matches the following pr ...

  3. openwrt下和云端通讯的例程,

    openwrt下和云端通讯的例程 ibcurl 官方文档请参考这里 http://curl.haxx.se/libcurl/c/curl_easy_setopt.html 刚接触 libcurl的时候 ...

  4. (转)利用libcurl获取新浪股票接口, ubuntu和openwrt实验成功(三)

    1.  利用 CURLOPT_WRITEFUNCTION 设置回调函数, 利用 CURLOPT_WRITEDATA 获取数据指针 官网文档如下 CALLBACK OPTIONS CURLOPT_WRI ...

  5. [笔记]linux下和windows下的 创建线程函数

    linux下和windows下的 创建线程函数 #ifdef __GNUC__ //Linux #include <pthread.h> #define CreateThreadEx(ti ...

  6. linux 下进程通讯详解

    linux 下进程通讯方法主要有以下六种: 1.管道 2.信号 3.共享内存 4.消息队列 5.信号量 6.socket

  7. 【转帖】Linux发行版:CentOS、Ubuntu、RedHat、Android、Tizen、MeeGo

     Linux发行版:CentOS.Ubuntu.RedHat.Android.Tizen.MeeGo作者:阳光岛主 原文在这儿 Linux,最早由Linus Benedict Torvalds在199 ...

  8. Linux 进程间通讯方式 pipe()函数 (转载)

    转自:http://blog.csdn.net/ta893115871/article/details/7478779 Linux 进程间通讯方式有以下几种: 1->管道(pipe)和有名管道( ...

  9. 【原创】xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(三)--实时与非实时数据交互

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有问题,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 目录 1.概述 1.概述 [原创]实时IPC概述 [ ...

随机推荐

  1. .NET面试题系列[8] - 泛型

    “可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...

  2. Java初始化过程

    这篇文章主要讲解Java在创建对象的时候,初始化的顺序.主要从以下几个例子中讲解: 继承关系中初始化顺序 初始化块与构造器的顺序 已经加载过的类的初始化顺序 加载父类,会不会加载子类 创建子类对象会不 ...

  3. Partition2:对表分区

    在SQL Server中,普通表可以转化为分区表,而分区表不能转化为普通表,普通表转化成分区表的过程是不可逆的,将普通表转化为分区表的方法是: 在分区架构(Partition Scheme)上创建聚集 ...

  4. 08.LoT.UI 前后台通用框架分解系列之——多样的Tag选择器

    LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/du ...

  5. HTML5 语义元素(一)页面结构

    本篇主要介绍HTML5增加的语义元素中关于页面结构方面的,包含: <article>.<aside>.<figure>.<figcaption>.< ...

  6. MVVM TextBox的键盘事件

    MVVM下RichTextBox的键盘回车事件设置为发送,不是回车 xmlns:i="http://schemas.microsoft.com/expression/2010/interac ...

  7. .Net 分布式云平台基础服务建设说明概要

    1)  背景 建设云平台的基础框架,用于支持各类云服务的业务的构建及发展. 2)  基础服务 根据目前对业务的理解和发展方向,总结抽象出以下几个基础服务,如图所示 3)  概要说明 基础服务的发展会根 ...

  8. jQuery2.x源码解析(缓存篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...

  9. Twproject Gantt开源甘特图功能扩展

    1.Twproject Gantt甘特图介绍 Twproject Gantt 是一款基于 jQuery 开发的甘特图组件,也可以创建其它图表,例如任务树(Task Trees).内置编辑.缩放和 CS ...

  10. JavaWeb——Listener

    一.基本概念 JavaWeb里面的listener是通过观察者设计模式进行实现的.对于观察者模式,这里不做过多介绍,大概讲一下什么意思. 观察者模式又叫发布订阅模式或者监听器模式.在该模式中有两个角色 ...