智能家居系统数据库设计与服务器客户端通信
智能家居系统数据库设计与服务器客户端通信
数据库设计
-- 创建用户表
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);
}
运行
- 确保已安装SQLite3库。
- 创建名为 "database.db" 的数据库文件,并根据上述SQL语句创建用户表和智能家居状态表。
- 编译并运行服务器程序。
- 编译并运行客户端程序。
- 点击客户端的 "Connect" 按钮,尝试连接服务器。
- 连接成功后,客户端会向服务器发送 userid,服务器会从数据库中获取对应的信息,生成建议并发送给客户端,客户端将建议显示在界面上。
注意
- 本代码仅为示例,实际使用时需要根据具体需求进行修改和完善。
- 建议消息的生成逻辑可以根据实际情况进行调整。
- 安全方面,需要对用户输入进行验证,并对数据库连接进行安全配置。
- 可以使用其他语言或框架编写客户端程序。
- 服务器和客户端需要在同一网络环境下才能进行通信。
- 在实际项目中,建议使用更完善的数据库管理和网络通信框架。
- 可以考虑使用其他通信协议,例如MQTT,来实现服务器和客户端之间的通信。
- 可以使用图形界面设计工具来设计更友好的客户端界面。
原文地址: http://www.cveoy.top/t/topic/fB7q 著作权归作者所有。请勿转载和采集!