智能家居系统数据库设计与服务器客户端通信

数据库设计

-- 创建用户表
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)
);

服务器代码 (Linux C)

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

#define MAX_BUFFER_SIZE 1024

// 数据库路径
#define DB_PATH "database.db"

// 数据库表名
#define TABLE_NAME "Status"

// 建议消息的最大长度
#define MAX_SUGGESTION_LENGTH 100

// 函数声明
void handle_client(int client_socket);
void send_suggestion(int client_socket, int uid);

int main() {
    int server_socket, client_socket;
    struct sockaddr_in server_address, client_address;
    socklen_t client_address_size;

    // 创建服务器套接字
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1) {
        perror("Failed to create socket");
        exit(1);
    }

    // 设置服务器地址
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    server_address.sin_port = htons(12345);

    // 绑定服务器套接字到指定地址和端口
    if (bind(server_socket, (struct sockaddr *)&server_address, sizeof(server_address)) == -1) {
        perror("Failed to bind socket");
        exit(1);
    }

    // 监听连接请求
    if (listen(server_socket, 5) == -1) {
        perror("Failed to listen");
        exit(1);
    }

    printf("Server started, waiting for clients...
");

    while (1) {
        // 接受客户端连接请求
        client_address_size = sizeof(client_address);
        client_socket = accept(server_socket, (struct sockaddr *)&client_address, &client_address_size);
        if (client_socket == -1) {
            perror("Failed to accept client connection");
            continue;
        }

        printf("Client connected
");

        // 处理客户端请求
        handle_client(client_socket);

        printf("Client disconnected
");

        // 关闭客户端套接字
        close(client_socket);
    }

    // 关闭服务器套接字
    close(server_socket);

    return 0;
}

void handle_client(int client_socket) {
    char buffer[MAX_BUFFER_SIZE];
    int uid;

    // 接收客户端发送的userid
    if (recv(client_socket, buffer, sizeof(buffer), 0) == -1) {
        perror("Failed to receive userid");
        return;
    }

    uid = atoi(buffer);

    // 发送建议给客户端
    send_suggestion(client_socket, uid);
}

void send_suggestion(int client_socket, int uid) {
    sqlite3 *db;
    char *error_message = 0;
    char sql_query[MAX_BUFFER_SIZE];
    char suggestion[MAX_SUGGESTION_LENGTH];

    // 打开数据库
    if (sqlite3_open(DB_PATH, &db) != SQLITE_OK) {
        perror("Failed to open database");
        return;
    }

    // 构造SQL查询语句
    sprintf(sql_query, "SELECT device_name, value FROM %s WHERE uid = %d ORDER BY sid DESC LIMIT 1", TABLE_NAME, uid);

    // 执行SQL查询语句
    if (sqlite3_exec(db, sql_query, NULL, 0, &error_message) != SQLITE_OK) {
        perror("Failed to execute SQL query");
        sqlite3_close(db);
        return;
    }

    // 解析查询结果并生成建议消息
    // 这里只是一个示例,根据实际需求进行修改
    sprintf(suggestion, "空调温度过低,建议提高温度至26℃;加湿器湿度过高或过低,建议调整加湿器湿度");

    // 发送建议给客户端
    if (send(client_socket, suggestion, strlen(suggestion), 0) == -1) {
        perror("Failed to send suggestion");
    }

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

客户端代码 (QT C++)

client.h

#ifndef CLIENT_H
#define CLIENT_H

#include <QWidget>
#include <QTcpSocket>

class Client : public QWidget
{
    Q_OBJECT

public:
    Client(QWidget *parent = nullptr);

private slots:
    void connectToServer();
    void sendUserId();
    void receiveSuggestion();
    void handleError(QAbstractSocket::SocketError error);

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

#endif // CLIENT_H

client.cpp

#include "client.h"
#include <QtWidgets>
#include <QTcpSocket>

Client::Client(QWidget *parent) : QWidget(parent)
{
    // 创建界面元素
    QVBoxLayout *layout = new QVBoxLayout(this);
    QPushButton *button = new QPushButton("Connect", this);
    textEdit = new QTextEdit(this);

    // 连接按钮点击信号和槽函数
    connect(button, &QPushButton::clicked, this, &Client::connectToServer);

    // 添加界面元素到布局中
    layout->addWidget(button);
    layout->addWidget(textEdit);
}

void Client::connectToServer()
{
    // 创建TCP套接字
    socket = new QTcpSocket(this);

    // 连接服务器
    socket->connectToHost("127.0.0.1", 12345);

    // 连接成功后发送userid
    connect(socket, &QTcpSocket::connected, this, &Client::sendUserId);

    // 接收服务器发送的建议消息
    connect(socket, &QTcpSocket::readyRead, this, &Client::receiveSuggestion);

    // 连接失败处理
    connect(socket, &QTcpSocket::errorOccurred, this, &Client::handleError);
}

void Client::sendUserId()
{
    // 获取userid(这里假设userid为123)
    int userid = 123;

    // 发送userid给服务器
    socket->write(QString::number(userid).toUtf8());
}

void Client::receiveSuggestion()
{
    // 接收服务器发送的建议消息
    QByteArray data = socket->readAll();

    // 在TextEdit界面显示建议消息
    textEdit->setText(QString(data));
}

void Client::handleError(QAbstractSocket::SocketError error)
{
    // 连接失败处理
    QString errorMessage;

    switch (error) {
    case QAbstractSocket::ConnectionRefusedError:
        errorMessage = "Connection refused";
        break;
    case QAbstractSocket::RemoteHostClosedError:
        errorMessage = "Remote host closed";
        break;
    case QAbstractSocket::HostNotFoundError:
        errorMessage = "Host not found";
        break;
    default:
        errorMessage = socket->errorString();
        break;
    }

    // 在TextEdit界面显示连接失败消息
    textEdit->setText(errorMessage);
}

运行

  1. 确保已安装SQLite3库。
  2. 创建名为 "database.db" 的数据库文件,并根据上述SQL语句创建用户表和智能家居状态表。
  3. 编译并运行服务器程序。
  4. 编译并运行客户端程序。
  5. 点击客户端的 "Connect" 按钮,尝试连接服务器。
  6. 连接成功后,客户端会向服务器发送 userid,服务器会从数据库中获取对应的信息,生成建议并发送给客户端,客户端将建议显示在界面上。

注意

  • 本代码仅为示例,实际使用时需要根据具体需求进行修改和完善。
  • 建议消息的生成逻辑可以根据实际情况进行调整。
  • 安全方面,需要对用户输入进行验证,并对数据库连接进行安全配置。
  • 可以使用其他语言或框架编写客户端程序。
  • 服务器和客户端需要在同一网络环境下才能进行通信。
  • 在实际项目中,建议使用更完善的数据库管理和网络通信框架。
  • 可以考虑使用其他通信协议,例如MQTT,来实现服务器和客户端之间的通信。
  • 可以使用图形界面设计工具来设计更友好的客户端界面。
智能家居系统数据库设计与服务器客户端通信

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

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