智能家居系统:基于 C 语言服务器和 QT C++ 客户端的数据库交互
智能家居系统:基于 C 语言服务器和 QT C++ 客户端的数据库交互
该智能家居系统通过 C 语言编写服务器,QT C++ 编写客户端,实现设备状态信息获取和建议生成。
数据库:
-- 创建用户表
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)
);
服务器代码 (C 语言):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sqlite3.h>
#define PORT 8888
#define MAX_BUFFER_SIZE 1024
// 数据库文件路径
const char* DB_FILE = "database.db";
// 回调函数,用于处理查询结果
int callback(void* data, int argc, char** argv, char** azColName) {
// 获取客户端传递的建议数据
char* suggestion = (char*)data;
// 构造建议消息
char buf[MAX_BUFFER_SIZE];
snprintf(buf, MAX_BUFFER_SIZE, "设备:%s,数值:%s", argv[0], argv[1]);
// 将建议消息追加到建议数据中
strncat(suggestion, buf, MAX_BUFFER_SIZE - strlen(suggestion) - 1);
return 0;
}
// 处理客户端请求
void handle_client_request(int client_socket) {
char buffer[MAX_BUFFER_SIZE];
char suggestion[MAX_BUFFER_SIZE] = "";
// 接收客户端发送的userid
if (recv(client_socket, buffer, MAX_BUFFER_SIZE, 0) <= 0) {
printf("接收userid失败\n");
return;
}
// 将userid转换为整数
int uid = atoi(buffer);
// 连接数据库
sqlite3* db;
int rc = sqlite3_open(DB_FILE, &db);
if (rc) {
printf("无法打开数据库: %s\n", sqlite3_errmsg(db));
return;
}
// 查询最新的设备信息
char sql[MAX_BUFFER_SIZE];
snprintf(sql, MAX_BUFFER_SIZE, "SELECT device_name, value FROM Status WHERE uid = %d ORDER BY sid DESC LIMIT 1", uid);
rc = sqlite3_exec(db, sql, callback, suggestion, NULL);
if (rc != SQLITE_OK) {
printf("查询数据库失败: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return;
}
// 关闭数据库连接
sqlite3_close(db);
// 发送建议消息给客户端
if (strlen(suggestion) > 0) {
if (send(client_socket, suggestion, strlen(suggestion), 0) <= 0) {
printf("发送建议消息失败\n");
}
} else {
if (send(client_socket, "没有建议", strlen("没有建议"), 0) <= 0) {
printf("发送建议消息失败\n");
}
}
}
int main() {
int server_socket, client_socket;
struct sockaddr_in server_address, client_address;
socklen_t client_address_length;
// 创建服务器套接字
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
printf("创建套接字失败\n");
return 1;
}
// 设置服务器地址
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(PORT);
// 绑定服务器地址到套接字
if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
printf("绑定地址失败\n");
return 1;
}
// 监听连接请求
if (listen(server_socket, 5) < 0) {
printf("监听失败\n");
return 1;
}
printf("服务器启动,等待连接…\n");
while (1) {
// 接受客户端连接
client_address_length = sizeof(client_address);
client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_address_length);
if (client_socket < 0) {
printf("接受连接失败\n");
continue;
}
printf("客户端连接成功\n");
// 处理客户端请求
handle_client_request(client_socket);
// 关闭客户端套接字
close(client_socket);
}
// 关闭服务器套接字
close(server_socket);
return 0;
}
客户端代码 (QT C++):
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QTextEdit>
#include <QTcpSocket>
#include <QHostAddress>
#include <QString>
class MainWindow : public QWidget {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr) : QWidget(parent) {
// 创建按钮
QPushButton* connectButton = new QPushButton("连接服务器", this);
connectButton->setGeometry(10, 10, 100, 30);
connect(connectButton, &QPushButton::clicked, this, &MainWindow::connectToServer);
// 创建文本编辑框
textEdit = new QTextEdit(this);
textEdit->setGeometry(10, 50, 300, 200);
}
private slots:
void connectToServer() {
// 创建 TCP 套接字
socket = new QTcpSocket(this);
// 连接服务器
socket->connectToHost(QHostAddress("127.0.0.1"), 8888);
// 连接成功
if (socket->waitForConnected(5000)) {
textEdit->append("连接成功!");
// 发送用户 ID
QString userId = "1"; // 替换为实际用户 ID
socket->write(userId.toUtf8());
socket->flush();
// 接收服务器建议
connect(socket, &QTcpSocket::readyRead, this, &MainWindow::readServerData);
} else {
// 连接失败
textEdit->append("连接失败!");
}
}
void readServerData() {
// 接收服务器数据
QByteArray data = socket->readAll();
QString msg = QString::fromUtf8(data);
textEdit->append(msg);
}
private:
QTcpSocket* socket;
QTextEdit* textEdit;
};
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
工作流程:
- 客户端连接服务器。
- 客户端发送用户 ID (uid) 给服务器。
- 服务器根据用户 ID 从数据库查询最新的设备状态信息。
- 服务器分析设备状态信息,生成建议并发送给客户端。
- 客户端接收并显示服务器的建议。
注意:
- 代码示例仅提供基本功能,需要根据实际应用场景进行完善。
- 实际应用中需要进行错误处理和安全措施,例如数据校验、身份验证等。
- 可以根据需要修改数据库结构和建议逻辑。
示例:
假设用户 ID 为 1,空调温度为 22 摄氏度,加湿器湿度为 30%。服务器分析后,生成以下建议:
“空调温度过低,建议提高温度至 26℃;加湿器湿度过低,建议调整加湿器湿度。”
该建议将显示在客户端的 GUI 上。
总结:
该智能家居系统实现了设备状态信息的获取和建议生成功能,可以帮助用户更好地管理和使用智能家居设备。
相关资源:
原文地址: https://www.cveoy.top/t/topic/fB6J 著作权归作者所有。请勿转载和采集!