Yeelink平台查询开关量——套接字编程 Windows平台

1.前言
    【2014年4月重写该博文】
    曾想使用STM32+LwIP实现一个yeelink应用,但是基础知识不够所以只能耐心学习。提到LwIP自然想到socket套接字,为了降低学习难度便从windwos平台的套接字开始入手。本文使用windows平台的套接字实现向eelink平台请求开关量状态,然后把HTTP响应打印至控制台。
    【相关博文】
    【 MinGW安装和使用总结 
    【Yeelink Http请求格式分析】
    【Yeelink平台使用——远程控制 RT Thread + LwIP+ STM32 】
    
2.运行
    【工作流程】    
    先看运行结果,大致的过程分为三块。第一部分,进行DNS地址解析;第二部分,发送HTTP请求;第三部分,接收HTTP响应
Yeelink平台查询开关量——套接字编程 Windows平台_第1张图片
图1 运行结果
    【运行设置】
若使用minGW+eclipse开发方式,需要加入wsock32库,添加的方法如下:

图2 添加wsock32库

3.参考代码

int main(int argc, char **argv)
{
    WSADATA wsaData;
    int result_id;
    int socket_id;
   
    // HTTP请求
    char send_buf[] =
    "GET /v1.0/device/1949/sensor/2511/datapoints HTTP/1.1\r\n"
    "U-ApiKey: [your apikey]\r\n"
    "Host: api.yeelink.net\r\n\r\n";
    // HTTP响应
    char receive_buf[1024];
    struct hostent *yeelink_host; // yeelink主机DNS解析结构体
    char *host_name = "api.yeelink.net"; // yeelink域名
    struct in_addr yeelink_ipaddr; // yeelink IP地址
    struct sockaddr_in yeelink_sockaddr; // yeelink 连接套接字
   
    // Winsows下启用socket
    result_id = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (result_id != 0) {
        printf("WSAStartup failed: %d\n", result_id);
        return 1;
    }
    // 第一步 DNS地址解析
    printf("calling gethostbyname with: %s\r\n", host_name);
    yeelink_host = gethostbyname(host_name);
    if (yeelink_host == NULL)
    {
        // DNS解析失败
        printf("error\r\n");
    }
    else
    {
        // DNS解析正确
        yeelink_ipaddr.s_addr = *(u_long *) yeelink_host->h_addr_list[0];
        printf("Yeelink IP Address %s\r\n" , inet_ntoa(yeelink_ipaddr));
    }
    // 第二步 创建套接字
    socket_id = socket(AF_INET, SOCK_STREAM, 0);
    yeelink_sockaddr.sin_family = AF_INET;
    yeelink_sockaddr.sin_port = htons(80); // 设置端口号
    yeelink_sockaddr.sin_addr = yeelink_ipaddr; // 设置IP地址
    memset(&(yeelink_sockaddr.sin_zero), 0, sizeof(yeelink_sockaddr.sin_zero));
    // 第三步 连接yeelink
    result_id = connect( socket_id, (struct sockaddr *)&yeelink_sockaddr, sizeof(struct sockaddr));
    if( result_id == SOCKET_ERROR )
    {
        printf("connect ok\r\n");
    }
    printf("Http request:\r\n%s\r\n",send_buf);
   
    // 第四步 发送HTTP请求
    send(socket_id , send_buf,strlen(send_buf), 0);
    // 第五步 接收HTTP响应
    int bytes_received = 0;
    bytes_received = recv( socket_id , receive_buf , 1024 , 0);
    receive_buf[ bytes_received ] = '\0';
    printf("Receive Message:\r\n%s\r\n",receive_buf );
    closesocket(socket_id); // 关闭套接字
    WSACleanup(); // windows下释放套接字
    getchar(); // 保持控制台窗口
    return 0;
}

4.若干说明
    【关于HTTP请求】
        注意请求的最后部分一定是连续两组\r\n,如果查看相关文档的话,HTTP请求以一空行结束(\r\n),考虑到上一行的回车换行所以是两组\r\n。

    【关于struct in_addr】
        可理解为一个IP地址,一个IP地址为一个32位整数。

    【关于struct sockaddr_in】
        可理解为套接字信息,一个套接字可能包括目标IP地址、端口号和协议类型等信息。所以struct sockaddr_in要比struct in_addr所占的字节数更大一些。

    【关于struct hostent】
        保存DNS解析结果的结构体,其中最为关键的域名的P地址存于h_addr_list数组中,由于一个域名可能对应多个IP地址,可取h_addr_list数组中的第一个(下标为0)。

5.总结
    熟悉了windows环境下的套接字编程,那么借助RT Thread轻松实现STM32+LwIP的方式和yeelink交互数据。

6.参考资料
【Yeelink Http请求格式分析】
【Yeelink平台使用——远程控制 RT Thread + LwIP+ STM32 】——后续博文

你可能感兴趣的:(socket,套接字,yeelink)