Qt网络编程-写一个简单的网络调试助手

环境

Windows:Qt5.15.2(VS2022)

Linux:Qt5.12.12(gcc)

源代码

TCP服务器

头文件:

#ifndef TCPSERVERWIDGET_H
#define TCPSERVERWIDGET_H
#include <QWidget>
namespace Ui {
class TCPServerWidget;
}
class QTcpServer;
class QTcpSocket;
class TCPServerWidget : public QWidget {
    Q_OBJECT
public:
    explicit TCPServerWidget(QWidget *parent = nullptr);
    ~TCPServerWidget();

private:
    QTcpSocket *socket(int row);
private slots:
    void on_listen_clicked();
    void on_close_clicked();
    void on_send_clicked();
    void on_clear_clicked();

private:
    Ui::TCPServerWidget *ui;
    QTcpServer *m_Server;
    QList<QTcpSocket *> m_Clients;
};
#endif // TCPSERVERWIDGET_H

源文件:

#include "tcpserverwidget.h"
#include "common.h"
#include "ui_tcpserverwidget.h"
#include <QHeaderView>
#include <QTcpServer>
#include <QTcpSocket>
TCPServerWidget::TCPServerWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::TCPServerWidget) {
    ui->setupUi(this);
    ui->localIp->addItem("Any");
    ui->localIp->addItems(getIPAddresses());
    ui->clientTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->clientTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->clientTable->horizontalHeader()->setSectionResizeMode(
        QHeaderView::Stretch);
    m_Server = new QTcpServer;
    connect(m_Server, &QTcpServer::newConnection, [=]() {
        QTcpSocket *tcpSocket = m_Server->nextPendingConnection();
        QString ip = tcpSocket->peerAddress().toString();
        quint16 port = tcpSocket->peerPort();
        appendLog(ui->textEdit, QString("%1:%2:connect").arg(ip).arg(port));
        bool r = false;
        for (int i = 0; i < ui->clientTable->rowCount(); ++i) {
            QTableWidgetItem *ipitem = ui->clientTable->item(i, 0);
            QTableWidgetItem *portitem = ui->clientTable->item(i, 1);
            if (nullptr != ipitem && nullptr != portitem &&
                ipitem->text() == ip && portitem->text().toUShort() == port) {
                r = true;
                break;
            }
        }
        connect(tcpSocket, &QTcpSocket::disconnected, [=]() {
            appendLog(ui->textEdit,
                      QString("%1:%2 disconnected")
                          .arg(tcpSocket->peerAddress().toString())
                          .arg(tcpSocket->peerPort()));
            for (int i = 0; i < ui->clientTable->rowCount(); ++i) {
                QTableWidgetItem *ipitem = ui->clientTable->item(i, 0);
                QTableWidgetItem *portitem = ui->clientTable->item(i, 1);
                if (nullptr != ipitem && nullptr != portitem &&
                    ipitem->text() == ip &&
                    portitem->text().toUShort() == port) {
                    ui->clientTable->removeRow(i);
                    break;
                }
            }
            for (QTcpSocket *socket : m_Clients) {
                if (ip == socket->peerAddress().toString() &&
                    port == socket->peerPort()) {
                    m_Clients.removeOne(socket);
                    socket = nullptr;
                    break;
                }
            }
        });
        connect(tcpSocket, &QTcpSocket::readyRead, [=]() {
            QByteArray data = (ui->toHex->isChecked())
                ? tcpSocket->readAll().toHex()
                : tcpSocket->readAll();
            appendLog(ui->textEdit,
                      QString("%1:%2:%3").arg(ip).arg(port).arg(QString(data)));
        });
        m_Clients.append(tcpSocket);
        int row = ui->clientTable->rowCount();
        ui->clientTable->insertRow(row);
        ui->clientTable->setItem(row, 0, new QTableWidgetItem(ip));
        ui->clientTable->setItem(row, 1,
                                 new QTableWidgetItem(QString::number(port)));
    });
}

TCPServerWidget::~TCPServerWidget() {
    delete ui;
}

QTcpSocket *TCPServerWidget::socket(int row) {
    QTableWidgetItem *ipitem = ui->clientTable->item(row, 0);
    QTableWidgetItem *portitem = ui->clientTable->item(row, 1);
    if (nullptr != ipitem && nullptr != portitem) {
        QString ip = ipitem->text();
        quint16 port = portitem->text().toUShort();
        for (QTcpSocket *tcpSocket : m_Clients) {
            if (ip == tcpSocket->peerAddress().toString() &&
                port == tcpSocket->peerPort())
                return tcpSocket;
        }
    }
    return nullptr;
}

void TCPServerWidget::on_listen_clicked() {

    if (ui->listen->text() == "listen") {
        if (m_Server->listen((ui->localIp->currentText() == "Any")
                                 ? QHostAddress::Any
                                 : QHostAddress(ui->localIp->currentText()),
                             ui->localPort->value())) {
            ui->listen->setText("listening");
            appendLog(ui->textEdit, "start listening");
        } else {
            appendLog(ui->textEdit,
                      "start listen error:" + m_Server->errorString());
        }
    } else {
        m_Server->close();
        ui->listen->setText("listen");
        for (QTcpSocket *tcpSocket : m_Clients) {
            tcpSocket->close();
            tcpSocket->disconnectFromHost();
        }
        m_Clients.clear();
        appendLog(ui->textEdit, "stop listening");
    }
}

void TCPServerWidget::on_close_clicked() {
    int row = ui->clientTable->currentRow();
    QTcpSocket *tcpSocket = socket(row);
    if (nullptr != tcpSocket) {
        tcpSocket->close();
        tcpSocket->disconnectFromHost();
    }
}

void TCPServerWidget::on_send_clicked() {
    QByteArray data = (ui->toHex->isChecked())
        ? QByteArray::fromHex(ui->message->text().toUtf8())
        : ui->message->text().toUtf8();
    int row = ui->clientTable->currentRow();
    QTcpSocket *tcpSocket = socket(row);
    if (nullptr != tcpSocket)tcpSocket->write(data, data.size());
}

void TCPServerWidget::on_clear_clicked() {
    ui->textEdit->clear();
}

TCP客户端

头文件:

#ifndef TCPCLIENTWIDGET_H
#define TCPCLIENTWIDGET_H

#include <QWidget>

namespace Ui {
class TCPClientWidget;
}

class QTcpSocket;
class TCPClientWidget : public QWidget {
    Q_OBJECT

public:
    explicit TCPClientWidget(QWidget *parent = nullptr);
    ~TCPClientWidget();

private slots:
    void on_connect_clicked();

    void on_send_clicked();

    void on_clear_clicked();

private:
    Ui::TCPClientWidget *ui;
    QTcpSocket *m_Socket;
};

#endif // TCPCLIENTWIDGET_H

源文件:

#include "tcpclientwidget.h"
#include "common.h"
#include "ui_tcpclientwidget.h"
#include <QFutureWatcher>
#include <QTcpSocket>
#include <QtConcurrent/QtConcurrent>

TCPClientWidget::TCPClientWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::TCPClientWidget) {
    ui->setupUi(this);
    ui->localIp->addItems(getIPAddresses());
    m_Socket = new QTcpSocket;
    connect(m_Socket, &QTcpSocket::disconnected, [=]() {
        ui->connect->setText("connect");
        appendLog(ui->textEdit, "disconnect");
    });
    connect(m_Socket, &QTcpSocket::readyRead, [=]() {
        QByteArray data = (ui->toHex->isChecked()) ? m_Socket->readAll().toHex()
                                                   : m_Socket->readAll();
        appendLog(ui->textEdit, QString(data));
    });
}

TCPClientWidget::~TCPClientWidget() {
    delete ui;
}

void TCPClientWidget::on_connect_clicked() {
    if ("connect" == ui->connect->text()) {
        if (ui->bind->isChecked()) {
            if (!m_Socket->bind(QHostAddress(ui->localIp->currentText()),
                                ui->localPort->value())) {
                appendLog(ui->textEdit,
                          "bind error:" + m_Socket->errorString());
                return;
            }
        }
        ui->connect->setEnabled(false);
        m_Socket->connectToHost(QHostAddress(ui->serverIp->text()),
                                ui->serverPort->value());
        if (m_Socket->waitForConnected()) {
            ui->connect->setText("disconnect");

            appendLog(ui->textEdit, "connect");
        } else
            appendLog(ui->textEdit, "connect error:" + m_Socket->errorString());
        ui->connect->setEnabled(true);
    } else {
        m_Socket->close();
        m_Socket->disconnectFromHost();
        ui->connect->setText("connect");
        appendLog(ui->textEdit, "disconnect");
    }
}

void TCPClientWidget::on_send_clicked() {
    QByteArray data = (ui->toHex->isChecked())
        ? QByteArray::fromHex(ui->message->text().toUtf8())
        : ui->message->text().toUtf8();
    if (m_Socket->isOpen()) m_Socket->write(data, data.size());
}

void TCPClientWidget::on_clear_clicked() {
    ui->textEdit->clear();
}

UDP

头文件:

#ifndef UDPWIDGET_H
#define UDPWIDGET_H

#include <QWidget>

namespace Ui {
class UDPWidget;
}

class QUdpSocket;
class UDPWidget : public QWidget {
  Q_OBJECT

 public:
  explicit UDPWidget(QWidget *parent = nullptr);
  ~UDPWidget();

 private slots:
  void on_bind_clicked();

  void on_send_2_clicked();

  void on_clear_2_clicked();

 private:
  Ui::UDPWidget *ui;
  QUdpSocket *m_Socket;
};

#endif  // UDPWIDGET_H

源文件:

#include "udpwidget.h"
#include <QUdpSocket>
#include "common.h"
#include "ui_udpwidget.h"

UDPWidget::UDPWidget(QWidget *parent) : QWidget(parent), ui(new Ui::UDPWidget) {
  ui->setupUi(this);
  ui->localIp_2->addItems(getIPAddresses());
  m_Socket = new QUdpSocket;
  connect(m_Socket, &QUdpSocket::readyRead, [=]() {
    while (m_Socket->hasPendingDatagrams()) {
      QByteArray data;
      QHostAddress host;
      quint16 port;
      data.resize(m_Socket->pendingDatagramSize());
      m_Socket->readDatagram(data.data(), data.size(), &host, &port);
      data = (ui->toHex_2->isChecked()) ? data.toHex() : data;
      appendLog(ui->textEdit, QString("%1:%2:%3")
                                  .arg(host.toString())
                                  .arg(port)
                                  .arg(QString(data)));
    }
  });
}

UDPWidget::~UDPWidget() { delete ui; }

void UDPWidget::on_bind_clicked() {
  if (ui->bind->text() == "bind") {
    if (m_Socket->bind(QHostAddress(ui->localIp_2->currentText()),
                       ui->localPort_2->value()))
      ui->bind->setText("unbind");
    else
      appendLog(ui->textEdit, "bind error:" + m_Socket->errorString());
  } else {
    m_Socket->abort();
    ui->bind->setText("bind");
  }
}

void UDPWidget::on_send_2_clicked() {
  QByteArray data = (ui->toHex_2->isChecked())
                        ? QByteArray::fromHex(ui->message_2->text().toUtf8())
                        : ui->message_2->text().toUtf8();
  m_Socket->writeDatagram(data, QHostAddress(ui->serverIp->text()),
                          ui->serverPort->value());
}

void UDPWidget::on_clear_2_clicked() { ui->textEdit->clear(); }

运行效果

TCP服务器与多个客户端通信:

UDP之间通信:

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>