Qt 服务器通信示例:使用 QTcpSocket 实现连接、数据发送与接收
#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_pushButton_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);
}
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_pushButton_clicked()
{
if (m_socket->state() == QAbstractSocket::ConnectedState) {
ui->message->append('已经连接上服务器');
return;
}
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();
QObject::connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, [=](QAbstractSocket::SocketError error) {
// 获取错误代码
QAbstractSocket::SocketError errorCode = m_socket->error();
// 根据错误代码进行相应处理
switch (errorCode) {
case QAbstractSocket::ConnectionRefusedError:
qDebug() << 'Connection refused';
break;
case QAbstractSocket::RemoteHostClosedError:
qDebug() << 'Remote host closed';
break;
// 其他错误处理...
default:
qDebug() << 'Unknown error';
break;
}
});
}
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();
}
代码改进建议:
- 将发送 userid 的代码移到
connected()函数中,使代码逻辑更清晰。 - 在
disconnected()函数中,提供更具体的连接失败信息,例如显示错误代码和错误信息。 - 在
readyRead()函数中,根据实际情况使用更具体的数据类型来解析服务器返回的数据,例如使用int、double或自定义结构体。 - 添加错误处理机制,例如连接失败后尝试重新连接、设置连接超时时间等。
- 对界面进行美化,添加交互功能,例如显示连接状态、发送按钮状态等。
示例代码说明:
- 该代码使用 QTcpSocket 类实现与服务器的连接,并发送和接收数据。
on_pushButton_clicked()函数处理连接按钮的点击事件,验证输入的 IP 地址和端口号,并尝试连接服务器。connected()函数在连接成功后发送 userid 给服务器。disconnected()函数在连接失败时处理连接断开事件,并显示错误信息。readyRead()函数处理服务器返回的数据,并将其解析和显示在界面上。
使用该代码需要注意以下几点:
- 需要根据实际情况修改服务器的 IP 地址和端口号。
- 需要根据服务器返回的数据格式修改数据解析代码。
- 需要添加必要的错误处理机制,确保程序的稳定性和可靠性。
其他建议:
- 使用信号和槽机制实现界面交互,例如将连接状态和发送按钮状态显示在界面上。
- 使用线程或异步操作提高程序性能,避免阻塞主线程。
- 使用 SSL/TLS 加密连接,确保数据传输安全。
- 使用日志记录功能,记录程序运行过程中的重要信息,方便调试和排查问题。
通过以上改进建议和代码说明,您可以更好地理解和使用该示例代码,并根据实际需求进行修改和扩展。
原文地址: https://www.cveoy.top/t/topic/fCbU 著作权归作者所有。请勿转载和采集!