智能家居系统开发:客户端和服务器交互设计

数据库设计

-- 创建用户表
CREATE TABLE IF NOT EXISTS users (
    uid INTEGER PRIMARY KEY AUTOINCREMENT,
    username varchar(10), 
    passwd varchar(10)
);


-- 创建智能家居状态表
CREATE TABLE IF NOT EXISTS Status (
    sid INTEGER PRIMARY KEY AUTOINCREMENT,
    uid INTEGER ,
    device_name varchar(10),
    device_state varchar(10),
    value varchar(10),
    mode varchar(10),
    FOREIGN KEY (uid) REFERENCES users (uid)
);

系统架构

  • 客户端:使用QT C++编写,负责与用户交互,收集用户输入并发送到服务器。
  • 服务器:使用Linux C编写,负责接收客户端请求,处理数据,连接数据库,并向客户端发送响应信息。

通信协议

  • 客户端和服务器之间通过HTTP协议进行通信。
  • 客户端将URL打包成JSON格式,并通过HTTP请求发送给服务器。
  • 服务器解析JSON数据,并根据数据内容进行相应操作。

服务器主要模块

  • void startServer():启动服务器,监听特定端口。
  • void acceptConnection():接受客户端连接。
  • void processClientData(string data):处理客户端发来的数据。
  • void sendDataToClient(string data):将数据发送给客户端。
  • void closeConnection():关闭与客户端的连接。
  • void viewData():查看客户端存储在SQLite智能家居状态表中温度和湿度数据。
  • void analyzeData():根据温度和湿度数据分析出合理建议。

工作流程

  1. 客户端收集用户输入,例如空调温度、加湿器湿度等信息。
  2. 客户端将数据打包成JSON格式,并通过HTTP请求发送给服务器。
  3. 服务器解析JSON数据,验证是否可以与客户端进行通信。
  4. 服务器连接SQLite数据库,根据Status表中的数据分析温度和湿度,并根据分析结果生成建议。
  5. 服务器将建议打包成JSON格式,并通过HTTP响应发送给客户端。
  6. 客户端接收服务器响应,并将建议显示在GUI界面上。

代码示例

客户端QT C++代码

#include <QApplication>
#include <QtNetwork>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QPushButton>
#include <QMessageBox>
#include <QTextEdit>

class Client : public QObject
{
    Q_OBJECT
public:
    explicit Client(QObject *parent = nullptr) : QObject(parent)
    {
        // 创建按钮和文本框
        QPushButton *button = new QPushButton('发送请求');
        connect(button, &QPushButton::clicked, this, &Client::sendRequest);
        button->show();

        QTextEdit *textEdit = new QTextEdit;
        textEdit->setReadOnly(true);
        textEdit->show();
        m_textEdit = textEdit;

        // 创建HTTP连接
        m_networkAccessManager = new QNetworkAccessManager(this);
        connect(m_networkAccessManager, &QNetworkAccessManager::finished, this, &Client::handleResponse);
    }

public slots:
    void sendRequest()
    {
        // 构造请求的JSON数据
        QJsonObject requestData;
        requestData['device_name'] = 'Air Conditioner';
        requestData['device_state'] = 'Temperature';
        requestData['value'] = '24';
        requestData['mode'] = 'Auto';

        QJsonDocument doc(requestData);
        QByteArray requestDataBytes = doc.toJson();

        QNetworkRequest request(QUrl('http://localhost:8080'));
        request.setHeader(QNetworkRequest::ContentTypeHeader, 'application/json');

        // 发送请求
        m_networkAccessManager->post(request, requestDataBytes);
    }

    void handleResponse(QNetworkReply *reply)
    {
        if (reply->error() == QNetworkReply::NoError) {
            // 解析服务器响应的JSON数据
            QByteArray responseData = reply->readAll();
            QJsonDocument doc = QJsonDocument::fromJson(responseData);
            QJsonObject responseDataObj = doc.object();

            QString suggestion = responseDataObj['suggestion'].toString();

            // 在GUI上显示服务器发送的建议
            m_textEdit->append(suggestion);
        } else {
            // 处理请求错误
            QMessageBox::critical(nullptr, 'Error', reply->errorString());
        }

        reply->deleteLater();
    }

private:
    QNetworkAccessManager *m_networkAccessManager;
    QTextEdit *m_textEdit;
};

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

    Client client;
    client.sendRequest();

    return a.exec();
}

#include "main.moc"

服务器端Linux C代码

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

#define PORT 8080

void processClientData(int clientSocket, const char *requestData)
{
    // 解析JSON数据
    // ...

    // 连接SQLite数据库
    sqlite3 *db;
    if (sqlite3_open('database.db', &db) != SQLITE_OK) {
        fprintf(stderr, 'Cannot open database: %s
', sqlite3_errmsg(db));
        return;
    }

    // 查询温度和湿度数据
    // ...

    // 分析数据,生成建议
    // ...

    // 构造响应的JSON数据
    // ...

    // 发送响应数据给客户端
    if (send(clientSocket, responseData, strlen(responseData), 0) < 0) {
        perror('send failed');
    }

    // 关闭与客户端的连接
    close(clientSocket);

    // 关闭数据库连接
    sqlite3_close(db);
}

void startServer()
{
    int serverSocket, clientSocket;
    struct sockaddr_in serverAddress, clientAddress;
    socklen_t clientAddressLength;

    // 创建套接字
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1) {
        perror('socket failed');
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址和端口
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_addr.s_addr = INADDR_ANY;
    serverAddress.sin_port = htons(PORT);

    // 绑定套接字到指定地址和端口
    if (bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) {
        perror('bind failed');
        exit(EXIT_FAILURE);
    }

    // 监听连接
    if (listen(serverSocket, 3) < 0) {
        perror('listen failed');
        exit(EXIT_FAILURE);
    }

    printf('Server started, listening on port %d
', PORT);

    while (1) {
        // 接受客户端连接
        clientAddressLength = sizeof(clientAddress);
        clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddress, &clientAddressLength);
        if (clientSocket < 0) {
            perror('accept failed');
            exit(EXIT_FAILURE);
        }

        printf('Client connected
');

        // 接收客户端发送的数据
        char requestData[1024];
        memset(requestData, 0, sizeof(requestData));
        if (recv(clientSocket, requestData, sizeof(requestData), 0) < 0) {
            perror('recv failed');
            exit(EXIT_FAILURE);
        }

        // 处理客户端数据
        processClientData(clientSocket, requestData);
    }
}

int main()
{
    startServer();

    return 0;
}

注意

  • 以上代码示例仅供参考,实际应用中可能需要进行错误处理、数据验证等更多的工作。
  • 数据库操作和JSON解析的代码需要根据具体的需求进行实现。

总结

本文介绍了一个简单的智能家居系统开发案例,展示了客户端和服务器之间通过HTTP协议和JSON数据进行交互的设计思路。在实际开发中,需要根据具体需求进行调整和完善。

智能家居系统开发:客户端和服务器交互设计

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

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