智能家居状态监控:Qt C++ 客户端与 Linux C 服务器交互
以下是一个示例代码,用于实现客户端 Qt C++ 存储在 sqlite 的智能家居状态表,并通过 TCP/IP 协议从 Linux C 服务器获取最新的温度和湿度数据,并根据数据制定建议发送给客户端。
客户端代码:
#include <QtWidgets>
#include <QTcpSocket>
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
class Client : public QWidget
{
Q_OBJECT
public:
Client(QWidget *parent = nullptr)
: QWidget(parent)
{
// 创建GUI界面
QVBoxLayout *layout = new QVBoxLayout(this);
QLabel *temperatureLabel = new QLabel('Temperature: ', this);
QLabel *humidityLabel = new QLabel('Humidity: ', this);
QLabel *suggestionLabel = new QLabel('Suggestion: ', this);
layout->addWidget(temperatureLabel);
layout->addWidget(humidityLabel);
layout->addWidget(suggestionLabel);
// 连接到服务器
socket = new QTcpSocket(this);
socket->connectToHost('127.0.0.1', 1234);
connect(socket, &QTcpSocket::readyRead, this, &Client::readData);
// 从数据库获取智能家居状态
QSqlDatabase db = QSqlDatabase::addDatabase('QSQLITE');
db.setDatabaseName('home.db');
if (!db.open()) {
QMessageBox::critical(this, 'Error', 'Failed to open database');
return;
}
QSqlQuery query;
if (!query.exec('SELECT * FROM home_status ORDER BY id DESC LIMIT 1')) {
QMessageBox::critical(this, 'Error', 'Failed to query database');
return;
}
if (query.next()) {
int temperature = query.value(1).toInt();
int humidity = query.value(2).toInt();
temperatureLabel->setText('Temperature: ' + QString::number(temperature) + '℃');
humidityLabel->setText('Humidity: ' + QString::number(humidity) + '%');
// 发送请求获取建议
socket->write('get_suggestion');
} else {
temperatureLabel->setText('Temperature: N/A');
humidityLabel->setText('Humidity: N/A');
}
}
private slots:
void readData()
{
// 读取服务器发送的建议
QByteArray data = socket->readAll();
QString suggestion = QString::fromUtf8(data);
// 显示建议
QLabel *suggestionLabel = findChild<QLabel*>('suggestionLabel');
suggestionLabel->setText('Suggestion: ' + suggestion);
}
private:
QTcpSocket *socket;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Client client;
client.show();
return app.exec();
}
#include "main.moc"
Linux C服务器代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define MAX_BUFFER_SIZE 1024
void handleClient(int clientSocket)
{
char buffer[MAX_BUFFER_SIZE];
ssize_t bytesRead;
// 从客户端接收请求
bytesRead = recv(clientSocket, buffer, sizeof(buffer), 0);
buffer[bytesRead] = '\0';
// 查询最新的温度和湿度数据
int temperature = 0;
int humidity = 0;
// 查询数据库并将结果存储在temperature和humidity变量中
// 制定建议
char suggestion[MAX_BUFFER_SIZE];
if (temperature < 24) {
sprintf(suggestion, 'Temperature is too low, suggest increasing temperature to 26℃');
} else if (humidity < 40 || humidity > 70) {
sprintf(suggestion, 'Humidity is too high or too low, suggest adjusting humidity');
} else {
sprintf(suggestion, 'No suggestion at the moment');
}
// 发送建议给客户端
send(clientSocket, suggestion, strlen(suggestion), 0);
close(clientSocket);
}
int main()
{
int serverSocket, clientSocket;
struct sockaddr_in serverAddress, clientAddress;
socklen_t clientAddressLength;
// 创建套接字
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == -1) {
perror('Failed to create socket');
exit(EXIT_FAILURE);
}
// 设置服务器地址
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(1234);
// 绑定套接字
if (bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) == -1) {
perror('Failed to bind socket');
exit(EXIT_FAILURE);
}
// 监听连接
if (listen(serverSocket, 5) == -1) {
perror('Failed to listen');
exit(EXIT_FAILURE);
}
while (1) {
// 接受客户端连接
clientAddressLength = sizeof(clientAddress);
clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddress, &clientAddressLength);
if (clientSocket == -1) {
perror('Failed to accept connection');
exit(EXIT_FAILURE);
}
// 处理客户端请求
handleClient(clientSocket);
}
// 关闭套接字
close(serverSocket);
return 0;
}
请注意,这只是一个简单的示例,实际应用中可能需要进行错误处理、数据验证和安全性考虑等。另外,数据库查询和建议制定的代码需要根据实际情况进行修改。
原文地址: https://www.cveoy.top/t/topic/fBmL 著作权归作者所有。请勿转载和采集!