智能家居状态监控系统:服务器和客户端代码

概述

本文介绍了一个简单的智能家居状态监控系统,包括服务器端和客户端代码。服务器使用 Linux C 语言编写,使用 SQLite 数据库存储智能家居设备状态信息。客户端使用 Qt C++ 编写,提供用户界面,并与服务器进行 TCP 通信。

服务器端代码(Linux C 语言)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sqlite3.h>

#define PORT 8080

// 数据库回调函数
static int callback(void *data, int argc, char **argv, char **azColName){
    int i;
    for(i=0; i<argc; i++){
        printf('%s = %s\n', azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

int main() {
    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1024] = {0};
    char *hello = "Hello from server";
    
    // 创建套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }
    
    // 设置套接字选项
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );
    
    // 绑定套接字到指定端口
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    
    // 监听套接字
    if (listen(server_fd, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    
    // 连接数据库
    sqlite3 *db;
    int rc;
    rc = sqlite3_open("database.db", &db);
    if(rc){
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        return 0;
    }else{
        fprintf(stderr, "Opened database successfully\n");
    }
    
    // 接受客户端连接
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }
    
    // 从客户端接收userid
    char userid[10];
    memset(userid, 0, sizeof(userid));
    valread = read(new_socket , userid, sizeof(userid));
    printf("Received userid: %s\n", userid);
    
    // 查询数据库获取设备状态信息
    char sql[100];
    sprintf(sql, "SELECT device_name, value FROM Status WHERE uid = %s", userid);
    rc = sqlite3_exec(db, sql, callback, 0, NULL);
    if(rc != SQLITE_OK){
        fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
    }
    
    // 分析设备状态信息并给出建议
    char suggestion[100];
    memset(suggestion, 0, sizeof(suggestion));
    // TODO: 根据设备状态信息分析并给出建议
    
    // 发送建议给客户端
    send(new_socket, suggestion, strlen(suggestion), 0);
    printf("Suggestion sent to client\n");
    
    // 关闭套接字和数据库连接
    close(new_socket);
    sqlite3_close(db);
    
    return 0;
}

客户端代码(Qt C++)

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QTextEdit>
#include <QTcpSocket>

class Client : public QWidget
{
    Q_OBJECT

public:
    Client(QWidget *parent = nullptr) : QWidget(parent)
    {
        // 创建界面元素
        QPushButton *connectButton = new QPushButton("Connect", this);
        connect(connectButton, &QPushButton::clicked, this, &Client::connectToServer);
        
        textEdit = new QTextEdit(this);
        textEdit->setReadOnly(true);
        
        // 设置界面布局
        QVBoxLayout *layout = new QVBoxLayout(this);
        layout->addWidget(connectButton);
        layout->addWidget(textEdit);
        setLayout(layout);
        
        // 创建TCP套接字
        socket = new QTcpSocket(this);
        connect(socket, &QTcpSocket::connected, this, &Client::onConnected);
        connect(socket, &QTcpSocket::disconnected, this, &Client::onDisconnected);
        connect(socket, &QTcpSocket::readyRead, this, &Client::onReadyRead);
    }

private slots:
    void connectToServer()
    {
        // 连接服务器
        socket->connectToHost("127.0.0.1", 8080);
    }
    
    void onConnected()
    {
        // 连接成功,向服务器发送userid
        QString userid = "12345";  // TODO: 替换为获取userid的逻辑
        socket->write(userid.toUtf8());
        socket->waitForBytesWritten();
        
        textEdit->append("Connected to server");
    }
    
    void onDisconnected()
    {
        textEdit->append("Disconnected from server");
    }
    
    void onReadyRead()
    {
        // 接收服务器发送的建议
        QByteArray data = socket->readAll();
        QString suggestion = QString::fromUtf8(data);
        
        textEdit->append("Received suggestion: " + suggestion);
    }

private:
    QTextEdit *textEdit;
    QTcpSocket *socket;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Client client;
    client.show();

    return a.exec();
}

#include "main.moc"

注意:

  • 以上代码仅为示例,实际使用时需要根据具体需求进行修改和完善。
  • 服务器端代码中的 TODO 部分需要根据实际情况编写设备状态信息分析逻辑。
  • 客户端代码中的 TODO 部分需要实现获取 userid 的逻辑。
  • 服务器端代码使用了 sqlite3_open 函数连接数据库,该函数需要 sqlite3 库的支持,请确保系统已安装该库。
  • 客户端代码使用了 QTcpSocket 类进行 TCP 通信,需要 Qt 框架的支持,请确保系统已安装 Qt 框架。
  • 本代码示例中,服务器和客户端使用相同的端口 8080 进行通信,实际使用时建议使用不同的端口,并确保端口未被占用。
  • 在实际项目中,需要考虑代码的安全性,例如对用户输入进行验证,防止SQL注入等攻击。

总结

本文介绍了一个简单的智能家居状态监控系统,该系统使用服务器和客户端进行交互,并利用 SQLite 数据库存储设备状态信息。该系统能够根据设备状态信息分析并给出建议,帮助用户更好地管理智能家居设备。

智能家居状态监控系统:服务器和客户端代码

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

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