C语言socket编程实现智能家居服务器端:根据数据库信息向客户端发送建议

本文介绍如何使用C语言socket编程实现一个简单的智能家居服务器端。该服务器端可以根据数据库中的设备状态信息,向客户端发送相应的建议。

代码分析

以下是服务器端代码的主要部分:

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include 'handle.h'

// ... 其他函数定义 ...

void handleClientRequest(ServerContext *context) {
    // 接收客户端发送的userid
    int userid = receiveUserId(context->sockfd);
    if (userid == -1) {
        perror('接收userid失败');
        return;
    }

    printf('客户端已连接\n');
    printf('userid:%d\n', userid);

    // 根据userid查询数据库
    sqlite3_stmt *stmt = prepareStatement(context->db, userid);
    if (stmt == NULL) {
        fprintf(stderr, '无法执行的语句: %s\n', sqlite3_errmsg(context->db));
        return;
    }

    // 初始化设备状态结构体
    Status acStatus, humidifierStatus;
    initializeStatus(&acStatus);
    initializeStatus(&humidifierStatus);

    // 初始化建议字符串
    char suggestion[MAX_BUFFER_SIZE] = '';
    char humidifierSuggestion[MAX_BUFFER_SIZE] = '';

    // 用于标识空调和加湿器是否开启
    int acOpened = 0;
    int humidifierOpened = 0;

    // 遍历数据库查询结果
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        // 获取设备名称、状态和值
        int uid = sqlite3_column_int(stmt, 1);
        const unsigned char *device_name = sqlite3_column_text(stmt, 2);
        const unsigned char *device_state = sqlite3_column_text(stmt, 3);
        const unsigned char *value = sqlite3_column_text(stmt, 4);
     
        // 判断设备类型
        if (device_name != NULL && device_state != NULL && value != NULL ) {
            if (strcmp(device_name, '空调') == 0) {
                // 如果空调开启,则更新空调状态并生成建议
                if (strcmp(device_state, '开启') == 0){
                    updateAcStatus(&acStatus, uid, device_state, value);
                    generateAcSuggestion(&acStatus, suggestion);
                    acOpened = 1;
                }
            } else if (strcmp(device_name, '加湿器') == 0) {
                // 如果加湿器开启,则更新加湿器状态并生成建议
                if (strcmp(device_state, '开启') == 0){
                    updateAcStatus(&humidifierStatus, uid, device_state, value);
                    generateHumidifierSuggestion(&humidifierStatus, humidifierSuggestion);
                    humidifierOpened = 1;
                }
            }
        }
    }

    sqlite3_finalize(stmt);

    // 如果空调未开启,则设置建议为'空调未开启'
    if (!acOpened) {
            snprintf(suggestion, MAX_BUFFER_SIZE, '空调未开启');
        }

    // 如果加湿器未开启,则设置建议为'加湿器未开启'
        if (!humidifierOpened) {
            snprintf(humidifierSuggestion, MAX_BUFFER_SIZE, '加湿器未开启');
        }

    // 合并建议并发送给客户端
    char *combinedSuggestion = combineSuggestions(suggestion, humidifierSuggestion);
    sendSuggestion(context->sockfd, combinedSuggestion);
    printf('建议为:\n%s\n', combinedSuggestion);

    free(combinedSuggestion);

    // 关闭连接
    shutdown(context->sockfd, SHUT_RDWR);
    printf('按下Ctrl + Z登出...\n');
}

// ... 其他函数定义 ...

问题分析

您遇到的问题是,即使加湿器和空调都开启,服务器仍然会向客户端发送“加湿器未开启”和“空调未开启”的提示信息。

问题原因:

在代码中,用于标识空调和加湿器是否开启的变量 acOpenedhumidifierOpened 在每次循环迭代中都会被重置。也就是说,如果数据库中有多条关于空调或加湿器的记录,即使其中一条记录显示设备已开启,但只要有一条记录显示设备未开启,最终 acOpenedhumidifierOpened 的值都会是0,导致发送错误的提示信息。

解决方案:

acOpenedhumidifierOpened 的初始化移到循环外部,确保这两个变量的值能够正确反映空调和加湿器的最终开启状态。

修改后的代码

void handleClientRequest(ServerContext *context) {
    // ...

    // 用于标识空调和加湿器是否开启
    int acOpened = 0;
    int humidifierOpened = 0;

    while (sqlite3_step(stmt) == SQLITE_ROW) {
        // ...

        // 判断设备类型
        if (device_name != NULL && device_state != NULL && value != NULL ) {
            if (strcmp(device_name, '空调') == 0) {
                // 如果空调开启,则更新空调状态并生成建议
                if (strcmp(device_state, '开启') == 0){
                    // ...
                    acOpened = 1; // 更新acOpened状态
                }
            } else if (strcmp(device_name, '加湿器') == 0) {
                // 如果加湿器开启,则更新加湿器状态并生成建议
                if (strcmp(device_state, '开启') == 0){
                    // ...
                    humidifierOpened = 1; // 更新humidifierOpened状态
                }
            }
        }
    }

    // ...
}

通过以上修改,代码就能正确判断空调和加湿器的开启状态,并向客户端发送正确的建议信息。

C语言socket编程实现智能家居服务器端:根据数据库信息向客户端发送建议

原文地址: https://www.cveoy.top/t/topic/fDPY 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录