智能家居服务器通信:使用QTcpSocket实现连接和数据交互
创建用户表
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)
);
使用QTcpSocket实现服务器通信
#ifndef PROCESSION_H
#define PROCESSION_H
#include <QWidget>
#include <QTcpSocket>
namespace Ui {
class Procession;
}
class Procession : public QWidget
{
Q_OBJECT
public:
explicit Procession(int userid, QWidget *parent = nullptr);
~Procession();
private slots:
void on_connectBtn_clicked();
void connected();
void disconnected();
void readyRead();
void displayError(QAbstractSocket::SocketError error);
private:
Ui::Procession *ui;
int userid;
QTcpSocket* m_socket;
};
#endif // PROCESSION_H
#include 'procession.h'
#include 'ui_procession.h'
#include <QAbstractSocket>
#include <QDebug>
Procession::Procession(int userid, QWidget *parent) :
QWidget(parent),
ui(new Ui::Procession),
userid(userid)
{
ui->setupUi(this);
processionWidget();
m_socket = new QTcpSocket(this);
connect(ui->connectBtn, &QPushButton::clicked, this, &Procession::on_connectBtn_clicked);
connect(m_socket, &QTcpSocket::readyRead, this, &Procession::readyRead);
connect(m_socket, &QTcpSocket::connected, this, &Procession::connected);
connect(m_socket, &QTcpSocket::disconnected, this, &Procession::disconnected);
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &Procession::displayError);
}
Procession::~Procession()
{
delete ui;
}
void Procession::processionWidget()
{
setWindowTitle('服务器通信');
setAutoFillBackground(true);
QPalette palette = this->palette();
QPixmap pixmap(':/user/image/image/net.jpg');
palette.setBrush(QPalette::Window, QBrush(pixmap));
setPalette(palette);
setFixedSize(600, 400);
}
void Procession::on_connectBtn_clicked()
{
if (m_socket->state() == QAbstractSocket::ConnectedState) {
m_socket->disconnectFromHost(); // 先关闭套接字
}
ui->message->append('已经连接上服务器');
QString ip = ui->IP->text();
QString port = ui->port->text();
if (ip.isEmpty() || port.isEmpty()) {
ui->message->clear();
ui->message->append('请输入有效的IP地址和端口号');
return;
}
ui->message->clear();
ui->message->append('正在连接中...');
m_socket->connectToHost(ip, static_cast<quint16>(ui->port->text().toInt()));
}
void Procession::connected()
{
ui->message->append('连接成功');
// 发送userid给服务器
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << this->userid;
if (m_socket->write(block) == -1) {
ui->message->append('发送userid失败');
m_socket->close();
}
}
void Procession::disconnected()
{
ui->message->append('连接失败');
m_socket->close();
}
void Procession::readyRead()
{
QByteArray data = m_socket->readAll();
if (data.isEmpty()) {
ui->message->append('读取的数据为空');
return;
}
// 解析服务器返回的数据
QDataStream in(&data, QIODevice::ReadOnly);
QString suggestion;
in >> suggestion; // 使用重载的 >> 运算符来读取数据
if (in.status() != QDataStream::Ok) {
ui->message->append('解析服务器返回的数据失败');
return;
}
ui->message->append(suggestion);
m_socket->close();
}
void Procession::displayError(QAbstractSocket::SocketError error)
{
QString errorMessage;
switch (error) {
case QAbstractSocket::ConnectionRefusedError:
errorMessage = '连接被拒绝';
break;
case QAbstractSocket::RemoteHostClosedError:
errorMessage = '远程主机关闭';
break;
case QAbstractSocket::HostNotFoundError:
errorMessage = '未找到主机';
break;
case QAbstractSocket::SocketTimeoutError:
errorMessage = '连接超时';
break;
case QAbstractSocket::NetworkError:
errorMessage = '网络错误';
break;
default:
errorMessage = '未知错误';
break;
}
ui->message->append('连接失败:' + errorMessage);
}
代码解释:
- 创建用户表和状态表: 代码展示了创建用户表和智能家居状态表的SQL语句,方便存储用户信息和设备状态。
- 使用QTcpSocket建立连接: 代码中使用QTcpSocket类来实现服务器连接,并监听连接成功、断开、数据读取和错误等事件。
- 发送用户ID: 连接成功后,程序会将用户的ID发送给服务器,以便服务器识别用户身份。
- 解析服务器返回的数据: 代码使用QDataStream类解析服务器返回的数据,并将结果显示在UI界面上。
- 处理连接错误: 代码中使用switch语句处理各种连接错误,并显示相应的错误信息。
总结:
本文介绍了使用QTcpSocket实现智能家居服务器通信的步骤,并提供了相应的代码示例。希望本文能够帮助您更好地理解QTcpSocket的使用方法,并能够将其应用到您的智能家居项目中。
注意:
本文中的代码仅供参考,具体实现方式可能需要根据实际情况进行调整。
原文地址: http://www.cveoy.top/t/topic/fCrb 著作权归作者所有。请勿转载和采集!