zoukankan      html  css  js  c++  java
  • (转)linux下和云端通讯的例程, ubuntu和openwrt实验成功(一)

    一.  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: T1u0027s 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. //返回参数: 之后的数据, 一般为有效数据, 如{"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 ", strerror(errno));
    50.       exit(1);
    51.   }
    52.   //客户程序开始建立sockfd描述符,建立SOCKET连接
    53.   if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    54.       fprintf(stderr, "Socket Error:%sa ",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 ", 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:%sa ",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 ", strerror(errno));
    77.             exit(0);
    78.         }
    79.     totalsend += send;
    80.     //DBG("%d bytes send OK! ", totalsend);
    81.   }
    82.   //DBG( " The following is the response header: ");
    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] == ' ' || buffer[0] == ' ') {
    91.                 i++;
    92.                 //DBG("i = %d, ", i);
    93.                 if (iRet == 0) {
    94.                     pc_tmp[iPos] = '';
    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] = '';
    111.   DBG(" ret(%d): %s ", 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 Host: %s Accept: */* %s Content-Length: %d Content-Type: application/x-www-form-urlencoded Connection: Close %s ",
    125.         pc_host_file, YEELINK_HOST, pc_header, len, pc_json);
    126.     DBG("request = %s ", 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 Host: %s Accept: */* %s Content-Length: %d Content-Type: application/x-www-form-urlencoded Connection: Close %s ",
    142.         LEWEI50_HOST_FILE, LEWEI50_HOST, pc_header, len, pc_json);
    143.     DBG("request = %s ", 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库的实现代码.

  • 相关阅读:
    Java中的集合类-详解
    wargames-Leviathan
    词霸阿涛的英语学习经历
    《小王子》阅读笔记
    linux的mysql密码忘了怎么办
    redis事务实现
    缓存穿透、缓存击穿、缓存雪崩
    单线程redis为什么快?
    redis和么memcached的区别
    如何解决缓存污染
  • 原文地址:https://www.cnblogs.com/alljoyn/p/4739963.html
Copyright © 2011-2022 走看看