#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();
}

代码改进建议:

  1. 将发送 userid 的代码移到 connected() 函数中,使代码逻辑更清晰。
  2. disconnected() 函数中,提供更具体的连接失败信息,例如显示错误代码和错误信息。
  3. readyRead() 函数中,根据实际情况使用更具体的数据类型来解析服务器返回的数据,例如使用 intdouble 或自定义结构体。
  4. 添加错误处理机制,例如连接失败后尝试重新连接、设置连接超时时间等。
  5. 对界面进行美化,添加交互功能,例如显示连接状态、发送按钮状态等。

示例代码说明:

  • 该代码使用 QTcpSocket 类实现与服务器的连接,并发送和接收数据。
  • on_pushButton_clicked() 函数处理连接按钮的点击事件,验证输入的 IP 地址和端口号,并尝试连接服务器。
  • connected() 函数在连接成功后发送 userid 给服务器。
  • disconnected() 函数在连接失败时处理连接断开事件,并显示错误信息。
  • readyRead() 函数处理服务器返回的数据,并将其解析和显示在界面上。

使用该代码需要注意以下几点:

  • 需要根据实际情况修改服务器的 IP 地址和端口号。
  • 需要根据服务器返回的数据格式修改数据解析代码。
  • 需要添加必要的错误处理机制,确保程序的稳定性和可靠性。

其他建议:

  • 使用信号和槽机制实现界面交互,例如将连接状态和发送按钮状态显示在界面上。
  • 使用线程或异步操作提高程序性能,避免阻塞主线程。
  • 使用 SSL/TLS 加密连接,确保数据传输安全。
  • 使用日志记录功能,记录程序运行过程中的重要信息,方便调试和排查问题。

通过以上改进建议和代码说明,您可以更好地理解和使用该示例代码,并根据实际需求进行修改和扩展。

Qt 服务器通信示例:使用 QTcpSocket 实现连接、数据发送与接收

原文地址: https://www.cveoy.top/t/topic/fCbU 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录