Qt C++ 客户端与 Linux C 服务器 HTTP 数据通信:实现智能家居建议功能
Qt C++ 客户端与 Linux C 服务器 HTTP 数据通信:实现智能家居建议功能
本文将介绍使用 Qt C++ 客户端和 Linux C 服务器进行 HTTP 数据通信,并实现一个简单的智能家居建议功能。客户端可以连接服务器,发送消息并接收服务器发送的建议,例如温度过低或湿度过高时的建议。
数据库表结构
首先,我们需要创建两个数据库表来存储用户信息和智能家居状态信息:
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++)
#include <QtWidgets>
#include <QtNetwork>
class Client : public QWidget
{
Q_OBJECT
public:
Client(QWidget *parent = nullptr);
private slots:
void connectToServer();
void sendMessage();
void receiveMessage();
void receiveAdvice();
private:
QLineEdit *ipLineEdit;
QLineEdit *portLineEdit;
QLineEdit *sendLineEdit;
QLineEdit *receiveLineEdit;
QLineEdit *adviceLineEdit;
QPushButton *connectButton;
QPushButton *sendButton;
QPushButton *getAdviceButton;
QTcpSocket *tcpSocket;
};
Client::Client(QWidget *parent)
: QWidget(parent)
{
ipLineEdit = new QLineEdit(this);
portLineEdit = new QLineEdit(this);
sendLineEdit = new QLineEdit(this);
receiveLineEdit = new QLineEdit(this);
adviceLineEdit = new QLineEdit(this);
connectButton = new QPushButton('Connect', this);
sendButton = new QPushButton('Send', this);
getAdviceButton = new QPushButton('Get Advice', this);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(new QLabel('IP Address:'));
layout->addWidget(ipLineEdit);
layout->addWidget(new QLabel('Port:'));
layout->addWidget(portLineEdit);
layout->addWidget(new QLabel('Send Message:'));
layout->addWidget(sendLineEdit);
layout->addWidget(new QLabel('Received Message:'));
layout->addWidget(receiveLineEdit);
layout->addWidget(new QLabel('Received Advice:'));
layout->addWidget(adviceLineEdit);
layout->addWidget(connectButton);
layout->addWidget(sendButton);
layout->addWidget(getAdviceButton);
setLayout(layout);
tcpSocket = new QTcpSocket(this);
connect(connectButton, &QPushButton::clicked, this, &Client::connectToServer);
connect(sendButton, &QPushButton::clicked, this, &Client::sendMessage);
connect(tcpSocket, &QTcpSocket::readyRead, this, &Client::receiveMessage);
connect(getAdviceButton, &QPushButton::clicked, this, &Client::receiveAdvice);
}
void Client::connectToServer()
{
QString ipAddress = ipLineEdit->text();
quint16 port = portLineEdit->text().toUShort();
tcpSocket->connectToHost(ipAddress, port);
connectButton->setEnabled(false);
}
void Client::sendMessage()
{
QString message = sendLineEdit->text();
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream << message;
tcpSocket->write(data);
}
void Client::receiveMessage()
{
QByteArray data = tcpSocket->readAll();
QDataStream stream(data);
QString message;
stream >> message;
receiveLineEdit->setText(message);
}
void Client::receiveAdvice()
{
QByteArray data = tcpSocket->readAll();
QDataStream stream(data);
QString advice;
stream >> advice;
adviceLineEdit->setText(advice);
}
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>
#define MAX_BUFFER_SIZE 1024
void sendAdvice(int clientSocket, const char *advice)
{
char buffer[MAX_BUFFER_SIZE];
memset(buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "%s", advice);
write(clientSocket, buffer, strlen(buffer));
}
int main()
{
int serverSocket, clientSocket;
struct sockaddr_in serverAddress, clientAddress;
socklen_t clientAddressLength = sizeof(clientAddress);
char buffer[MAX_BUFFER_SIZE];
// 创建服务器端socket
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 = INADDR_ANY;
serverAddress.sin_port = htons(12345);
// 绑定服务器端地址
if (bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) == -1) {
perror("Failed to bind address");
exit(EXIT_FAILURE);
}
// 监听连接请求
if (listen(serverSocket, 5) == -1) {
perror("Failed to listen");
exit(EXIT_FAILURE);
}
printf("Server listening on port 12345\n");
while (1) {
// 接受客户端连接
clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddress, &clientAddressLength);
if (clientSocket == -1) {
perror("Failed to accept connection");
exit(EXIT_FAILURE);
}
printf("Client connected: %s:%d\n", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port));
while (1) {
// 接收客户端消息
memset(buffer, 0, sizeof(buffer));
ssize_t bytesRead = read(clientSocket, buffer, sizeof(buffer));
if (bytesRead <= 0) {
break;
}
printf("Received message: %s\n", buffer);
// 处理智能家居状态表并发送建议
// TODO: 根据需求编写处理逻辑,生成建议消息
const char *advice = "空调温度过低,建议提高温度至26℃";
sendAdvice(clientSocket, advice);
}
printf("Client disconnected\n");
close(clientSocket);
}
close(serverSocket);
return 0;
}
代码说明
-
客户端代码
- 客户端使用
QTcpSocket类连接到服务器。 - 客户端包含五个
QLineEdit用于输入 IP 地址、端口、发送消息、接收消息和接收建议。 - 客户端包含三个
QPushButton用于连接、发送消息和获取建议。 connectToServer()函数用于连接到服务器。sendMessage()函数用于发送消息给服务器。receiveMessage()函数用于接收服务器发送的消息。receiveAdvice()函数用于接收服务器发送的建议。
- 客户端使用
-
服务器端代码
- 服务器使用
socket()函数创建套接字。 - 服务器使用
bind()函数绑定地址和端口。 - 服务器使用
listen()函数开始监听连接请求。 - 服务器使用
accept()函数接受客户端连接。 - 服务器使用
read()函数读取客户端发送的消息。 sendAdvice()函数用于将建议发送给客户端。
- 服务器使用
总结
以上代码实现了一个简单的 Qt C++ 客户端和 Linux C 服务器通信示例,并包含了智能家居建议功能。您可以根据自己的需求修改代码并添加更多功能,例如:
- 在服务器端根据智能家居状态表中的数据生成更复杂的建议。
- 在客户端 GUI 中添加更多控件,例如显示温度、湿度等信息。
- 使用更安全的通信协议,例如 HTTPS。
希望本文能帮助您了解如何使用 Qt C++ 和 Linux C 开发智能家居系统。
原文地址: https://www.cveoy.top/t/topic/fBns 著作权归作者所有。请勿转载和采集!