Qt C++客户端与Linux C服务器HTTP通信及智能家居建议
Qt C++客户端与Linux C服务器HTTP通信及智能家居建议实战
这篇博客将提供一个简单的示例,演示如何使用Qt C++编写客户端和Linux C编写服务器,实现两者之间的HTTP数据通信。此外,还将展示如何从智能家居状态表中获取最新的温度和湿度数据,并根据这些数据向客户端发送建议。
1. 数据库设计
首先,我们需要创建两个表:用户表和智能家居状态表。
用户表 (users):
CREATE TABLE IF NOT EXISTS users (
uid INTEGER PRIMARY KEY AUTOINCREMENT,
username varchar(10),
passwd varchar(10)
);
智能家居状态表 (Status):
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)
);
2. 客户端代码 (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 getAdvice();
private:
QLineEdit *urlLineEdit;
QLineEdit *sendMessageLineEdit;
QLineEdit *receiveMessageLineEdit;
QLineEdit *adviceLineEdit;
QPushButton *connectButton;
QPushButton *sendMessageButton;
QPushButton *getAdviceButton;
QNetworkAccessManager *networkManager;
QNetworkReply *reply;
void parseAdvice(const QString &advice);
};
Client::Client(QWidget *parent)
: QWidget(parent)
{
urlLineEdit = new QLineEdit('http://localhost:8080', this);
sendMessageLineEdit = new QLineEdit(this);
receiveMessageLineEdit = new QLineEdit(this);
adviceLineEdit = new QLineEdit(this);
connectButton = new QPushButton('Connect', this);
sendMessageButton = new QPushButton('Send Message', this);
getAdviceButton = new QPushButton('Get Advice', this);
networkManager = new QNetworkAccessManager(this);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(new QLabel('URL:', this));
layout->addWidget(urlLineEdit);
layout->addWidget(new QLabel('Send Message:', this));
layout->addWidget(sendMessageLineEdit);
layout->addWidget(new QLabel('Receive Message:', this));
layout->addWidget(receiveMessageLineEdit);
layout->addWidget(new QLabel('Advice:', this));
layout->addWidget(adviceLineEdit);
layout->addWidget(connectButton);
layout->addWidget(sendMessageButton);
layout->addWidget(getAdviceButton);
setLayout(layout);
connect(connectButton, &QPushButton::clicked, this, &Client::connectToServer);
connect(sendMessageButton, &QPushButton::clicked, this, &Client::sendMessage);
connect(getAdviceButton, &QPushButton::clicked, this, &Client::getAdvice);
connect(networkManager, &QNetworkAccessManager::finished, this, &Client::receiveMessage);
}
void Client::connectToServer()
{
QUrl url(urlLineEdit->text());
if (!url.isValid()) {
qDebug() << 'Invalid URL';
return;
}
QNetworkRequest request(url);
reply = networkManager->get(request);
}
void Client::sendMessage()
{
QUrl url(urlLineEdit->text());
if (!url.isValid()) {
qDebug() << 'Invalid URL';
return;
}
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, 'text/plain');
QByteArray message = sendMessageLineEdit->text().toUtf8();
reply = networkManager->post(request, message);
}
void Client::receiveMessage()
{
if (reply->error() == QNetworkReply::NoError) {
QString response = QString::fromUtf8(reply->readAll());
receiveMessageLineEdit->setText(response);
} else {
qDebug() << 'Error:' << reply->errorString();
}
reply->deleteLater();
}
void Client::getAdvice()
{
// Assuming the advice is obtained from the server in the response
QString response = receiveMessageLineEdit->text();
parseAdvice(response);
}
void Client::parseAdvice(const QString &advice)
{
// Parse the advice and display it in the GUI
adviceLineEdit->setText(advice);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Client client;
client.show();
return app.exec();
}
#include 'main.moc'
3. 服务器端代码 (Linux C)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERVER_PORT 8080
#define MAX_BUFFER_SIZE 1024
void handleClient(int clientSocket);
int main()
{
int serverSocket, clientSocket;
struct sockaddr_in serverAddress, clientAddress;
socklen_t clientAddressLength = sizeof(clientAddress);
// Create server socket
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket < 0) {
perror('Failed to create server socket');
exit(EXIT_FAILURE);
}
// Set server address
memset(&serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(SERVER_PORT);
// Bind server socket to server address
if (bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) {
perror('Failed to bind server socket');
exit(EXIT_FAILURE);
}
// Listen for incoming connections
if (listen(serverSocket, 1) < 0) {
perror('Failed to listen for connections');
exit(EXIT_FAILURE);
}
printf('Server listening on port %d\n', SERVER_PORT);
while (1) {
// Accept client connection
clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddress, &clientAddressLength);
if (clientSocket < 0) {
perror('Failed to accept client connection');
exit(EXIT_FAILURE);
}
printf('Client connected from %s:%d\n', inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port));
// Handle client request
handleClient(clientSocket);
// Close client socket
close(clientSocket);
printf('Client disconnected\n');
}
// Close server socket
close(serverSocket);
return 0;
}
void handleClient(int clientSocket)
{
char buffer[MAX_BUFFER_SIZE];
ssize_t bytesRead;
ssize_t bytesSent;
// Receive message from client
bytesRead = recv(clientSocket, buffer, sizeof(buffer), 0);
if (bytesRead < 0) {
perror('Failed to receive message from client');
exit(EXIT_FAILURE);
}
printf('Received message from client: %.*s\n', (int)bytesRead, buffer);
// **获取智能家居状态表最新的温度、湿度数据**
// (此处需要根据实际情况编写代码,例如连接数据库并查询数据)
// 例如:
float temperature = 22.5; // 从数据库获取的温度数据
int humidity = 35; // 从数据库获取的湿度数据
// **制定建议**
char advice[MAX_BUFFER_SIZE];
if (temperature < 24.0 && (humidity < 40 || humidity > 70)) {
snprintf(advice, sizeof(advice), '空调温度过低,建议提高温度至26℃;加湿器湿度过高或过低,建议调整加湿器湿度');
} else {
snprintf(advice, sizeof(advice), '当前环境舒适');
}
// Send advice to client
bytesSent = send(clientSocket, advice, strlen(advice), 0);
if (bytesSent < 0) {
perror('Failed to send advice to client');
exit(EXIT_FAILURE);
}
printf('Sent advice to client: %.*s\n', (int)bytesSent, advice);
}
4. GUI界面说明
GUI界面包含以下元素:
- 4个LineEdit:
- 网址:用于输入服务器地址和端口号。
- 客户端发送消息:用于输入要发送给服务器的消息。
- 客户端收到服务器端发送的消息:用于显示服务器返回的消息。
- 客户端收到服务器发送的建议:用于显示服务器根据智能家居状态发送的建议。
- 3个QPushButton按钮:
- 连接客户端和服务器端:用于建立客户端与服务器之间的连接。
- 客户端发送消息按键:用于向服务器发送消息。
- 客户端获取服务器端建议的按键:用于向服务器请求智能家居建议。
5. 总结
本文提供了一个简单的客户端Qt C++和Linux C服务器进行http数据通信的示例代码,并展示了如何从智能家居状态表中获取最新的温度和湿度数据,并根据这些数据向客户端发送建议。你可以根据自己的需求对代码进行修改和扩展,例如添加用户认证、数据加密等功能,构建更加完善的智能家居系统。
希望这篇文章能够帮助你理解如何使用Qt C++和Linux C进行网络编程,以及如何构建简单的智能家居系统。
原文地址: https://www.cveoy.top/t/topic/fBnv 著作权归作者所有。请勿转载和采集!