当前位置:   article > 正文

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

如何写一个网络调试助手

环境

Windows:Qt5.15.2(VS2022

Linux:Qt5.12.12(gcc)

源代码

TCP服务器

头文件:

  1. #ifndef TCPSERVERWIDGET_H
  2. #define TCPSERVERWIDGET_H
  3. #include <QWidget>
  4. namespace Ui {
  5. class TCPServerWidget;
  6. }
  7. class QTcpServer;
  8. class QTcpSocket;
  9. class TCPServerWidget : public QWidget {
  10. Q_OBJECT
  11. public:
  12. explicit TCPServerWidget(QWidget *parent = nullptr);
  13. ~TCPServerWidget();
  14. private:
  15. QTcpSocket *socket(int row);
  16. private slots:
  17. void on_listen_clicked();
  18. void on_close_clicked();
  19. void on_send_clicked();
  20. void on_clear_clicked();
  21. private:
  22. Ui::TCPServerWidget *ui;
  23. QTcpServer *m_Server;
  24. QList<QTcpSocket *> m_Clients;
  25. };
  26. #endif // TCPSERVERWIDGET_H

源文件:

  1. #include "tcpserverwidget.h"
  2. #include "common.h"
  3. #include "ui_tcpserverwidget.h"
  4. #include <QHeaderView>
  5. #include <QTcpServer>
  6. #include <QTcpSocket>
  7. TCPServerWidget::TCPServerWidget(QWidget *parent)
  8. : QWidget(parent), ui(new Ui::TCPServerWidget) {
  9. ui->setupUi(this);
  10. ui->localIp->addItem("Any");
  11. ui->localIp->addItems(getIPAddresses());
  12. ui->clientTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
  13. ui->clientTable->setSelectionBehavior(QAbstractItemView::SelectRows);
  14. ui->clientTable->horizontalHeader()->setSectionResizeMode(
  15. QHeaderView::Stretch);
  16. m_Server = new QTcpServer;
  17. connect(m_Server, &QTcpServer::newConnection, [=]() {
  18. QTcpSocket *tcpSocket = m_Server->nextPendingConnection();
  19. QString ip = tcpSocket->peerAddress().toString();
  20. quint16 port = tcpSocket->peerPort();
  21. appendLog(ui->textEdit, QString("%1:%2:connect").arg(ip).arg(port));
  22. bool r = false;
  23. for (int i = 0; i < ui->clientTable->rowCount(); ++i) {
  24. QTableWidgetItem *ipitem = ui->clientTable->item(i, 0);
  25. QTableWidgetItem *portitem = ui->clientTable->item(i, 1);
  26. if (nullptr != ipitem && nullptr != portitem &&
  27. ipitem->text() == ip && portitem->text().toUShort() == port) {
  28. r = true;
  29. break;
  30. }
  31. }
  32. connect(tcpSocket, &QTcpSocket::disconnected, [=]() {
  33. appendLog(ui->textEdit,
  34. QString("%1:%2 disconnected")
  35. .arg(tcpSocket->peerAddress().toString())
  36. .arg(tcpSocket->peerPort()));
  37. for (int i = 0; i < ui->clientTable->rowCount(); ++i) {
  38. QTableWidgetItem *ipitem = ui->clientTable->item(i, 0);
  39. QTableWidgetItem *portitem = ui->clientTable->item(i, 1);
  40. if (nullptr != ipitem && nullptr != portitem &&
  41. ipitem->text() == ip &&
  42. portitem->text().toUShort() == port) {
  43. ui->clientTable->removeRow(i);
  44. break;
  45. }
  46. }
  47. for (QTcpSocket *socket : m_Clients) {
  48. if (ip == socket->peerAddress().toString() &&
  49. port == socket->peerPort()) {
  50. m_Clients.removeOne(socket);
  51. socket = nullptr;
  52. break;
  53. }
  54. }
  55. });
  56. connect(tcpSocket, &QTcpSocket::readyRead, [=]() {
  57. QByteArray data = (ui->toHex->isChecked())
  58. ? tcpSocket->readAll().toHex()
  59. : tcpSocket->readAll();
  60. appendLog(ui->textEdit,
  61. QString("%1:%2:%3").arg(ip).arg(port).arg(QString(data)));
  62. });
  63. m_Clients.append(tcpSocket);
  64. int row = ui->clientTable->rowCount();
  65. ui->clientTable->insertRow(row);
  66. ui->clientTable->setItem(row, 0, new QTableWidgetItem(ip));
  67. ui->clientTable->setItem(row, 1,
  68. new QTableWidgetItem(QString::number(port)));
  69. });
  70. }
  71. TCPServerWidget::~TCPServerWidget() {
  72. delete ui;
  73. }
  74. QTcpSocket *TCPServerWidget::socket(int row) {
  75. QTableWidgetItem *ipitem = ui->clientTable->item(row, 0);
  76. QTableWidgetItem *portitem = ui->clientTable->item(row, 1);
  77. if (nullptr != ipitem && nullptr != portitem) {
  78. QString ip = ipitem->text();
  79. quint16 port = portitem->text().toUShort();
  80. for (QTcpSocket *tcpSocket : m_Clients) {
  81. if (ip == tcpSocket->peerAddress().toString() &&
  82. port == tcpSocket->peerPort())
  83. return tcpSocket;
  84. }
  85. }
  86. return nullptr;
  87. }
  88. void TCPServerWidget::on_listen_clicked() {
  89. if (ui->listen->text() == "listen") {
  90. if (m_Server->listen((ui->localIp->currentText() == "Any")
  91. ? QHostAddress::Any
  92. : QHostAddress(ui->localIp->currentText()),
  93. ui->localPort->value())) {
  94. ui->listen->setText("listening");
  95. appendLog(ui->textEdit, "start listening");
  96. } else {
  97. appendLog(ui->textEdit,
  98. "start listen error:" + m_Server->errorString());
  99. }
  100. } else {
  101. m_Server->close();
  102. ui->listen->setText("listen");
  103. for (QTcpSocket *tcpSocket : m_Clients) {
  104. tcpSocket->close();
  105. tcpSocket->disconnectFromHost();
  106. }
  107. m_Clients.clear();
  108. appendLog(ui->textEdit, "stop listening");
  109. }
  110. }
  111. void TCPServerWidget::on_close_clicked() {
  112. int row = ui->clientTable->currentRow();
  113. QTcpSocket *tcpSocket = socket(row);
  114. if (nullptr != tcpSocket) {
  115. tcpSocket->close();
  116. tcpSocket->disconnectFromHost();
  117. }
  118. }
  119. void TCPServerWidget::on_send_clicked() {
  120. QByteArray data = (ui->toHex->isChecked())
  121. ? QByteArray::fromHex(ui->message->text().toUtf8())
  122. : ui->message->text().toUtf8();
  123. int row = ui->clientTable->currentRow();
  124. QTcpSocket *tcpSocket = socket(row);
  125. if (nullptr != tcpSocket)tcpSocket->write(data, data.size());
  126. }
  127. void TCPServerWidget::on_clear_clicked() {
  128. ui->textEdit->clear();
  129. }

TCP客户端

头文件:

  1. #ifndef TCPCLIENTWIDGET_H
  2. #define TCPCLIENTWIDGET_H
  3. #include <QWidget>
  4. namespace Ui {
  5. class TCPClientWidget;
  6. }
  7. class QTcpSocket;
  8. class TCPClientWidget : public QWidget {
  9. Q_OBJECT
  10. public:
  11. explicit TCPClientWidget(QWidget *parent = nullptr);
  12. ~TCPClientWidget();
  13. private slots:
  14. void on_connect_clicked();
  15. void on_send_clicked();
  16. void on_clear_clicked();
  17. private:
  18. Ui::TCPClientWidget *ui;
  19. QTcpSocket *m_Socket;
  20. };
  21. #endif // TCPCLIENTWIDGET_H

源文件:

  1. #include "tcpclientwidget.h"
  2. #include "common.h"
  3. #include "ui_tcpclientwidget.h"
  4. #include <QFutureWatcher>
  5. #include <QTcpSocket>
  6. #include <QtConcurrent/QtConcurrent>
  7. TCPClientWidget::TCPClientWidget(QWidget *parent)
  8. : QWidget(parent), ui(new Ui::TCPClientWidget) {
  9. ui->setupUi(this);
  10. ui->localIp->addItems(getIPAddresses());
  11. m_Socket = new QTcpSocket;
  12. connect(m_Socket, &QTcpSocket::disconnected, [=]() {
  13. ui->connect->setText("connect");
  14. appendLog(ui->textEdit, "disconnect");
  15. });
  16. connect(m_Socket, &QTcpSocket::readyRead, [=]() {
  17. QByteArray data = (ui->toHex->isChecked()) ? m_Socket->readAll().toHex()
  18. : m_Socket->readAll();
  19. appendLog(ui->textEdit, QString(data));
  20. });
  21. }
  22. TCPClientWidget::~TCPClientWidget() {
  23. delete ui;
  24. }
  25. void TCPClientWidget::on_connect_clicked() {
  26. if ("connect" == ui->connect->text()) {
  27. if (ui->bind->isChecked()) {
  28. if (!m_Socket->bind(QHostAddress(ui->localIp->currentText()),
  29. ui->localPort->value())) {
  30. appendLog(ui->textEdit,
  31. "bind error:" + m_Socket->errorString());
  32. return;
  33. }
  34. }
  35. ui->connect->setEnabled(false);
  36. m_Socket->connectToHost(QHostAddress(ui->serverIp->text()),
  37. ui->serverPort->value());
  38. if (m_Socket->waitForConnected()) {
  39. ui->connect->setText("disconnect");
  40. appendLog(ui->textEdit, "connect");
  41. } else
  42. appendLog(ui->textEdit, "connect error:" + m_Socket->errorString());
  43. ui->connect->setEnabled(true);
  44. } else {
  45. m_Socket->close();
  46. m_Socket->disconnectFromHost();
  47. ui->connect->setText("connect");
  48. appendLog(ui->textEdit, "disconnect");
  49. }
  50. }
  51. void TCPClientWidget::on_send_clicked() {
  52. QByteArray data = (ui->toHex->isChecked())
  53. ? QByteArray::fromHex(ui->message->text().toUtf8())
  54. : ui->message->text().toUtf8();
  55. if (m_Socket->isOpen()) m_Socket->write(data, data.size());
  56. }
  57. void TCPClientWidget::on_clear_clicked() {
  58. ui->textEdit->clear();
  59. }

UDP

头文件:

  1. #ifndef UDPWIDGET_H
  2. #define UDPWIDGET_H
  3. #include <QWidget>
  4. namespace Ui {
  5. class UDPWidget;
  6. }
  7. class QUdpSocket;
  8. class UDPWidget : public QWidget {
  9. Q_OBJECT
  10. public:
  11. explicit UDPWidget(QWidget *parent = nullptr);
  12. ~UDPWidget();
  13. private slots:
  14. void on_bind_clicked();
  15. void on_send_2_clicked();
  16. void on_clear_2_clicked();
  17. private:
  18. Ui::UDPWidget *ui;
  19. QUdpSocket *m_Socket;
  20. };
  21. #endif // UDPWIDGET_H

源文件:

  1. #include "udpwidget.h"
  2. #include <QUdpSocket>
  3. #include "common.h"
  4. #include "ui_udpwidget.h"
  5. UDPWidget::UDPWidget(QWidget *parent) : QWidget(parent), ui(new Ui::UDPWidget) {
  6. ui->setupUi(this);
  7. ui->localIp_2->addItems(getIPAddresses());
  8. m_Socket = new QUdpSocket;
  9. connect(m_Socket, &QUdpSocket::readyRead, [=]() {
  10. while (m_Socket->hasPendingDatagrams()) {
  11. QByteArray data;
  12. QHostAddress host;
  13. quint16 port;
  14. data.resize(m_Socket->pendingDatagramSize());
  15. m_Socket->readDatagram(data.data(), data.size(), &host, &port);
  16. data = (ui->toHex_2->isChecked()) ? data.toHex() : data;
  17. appendLog(ui->textEdit, QString("%1:%2:%3")
  18. .arg(host.toString())
  19. .arg(port)
  20. .arg(QString(data)));
  21. }
  22. });
  23. }
  24. UDPWidget::~UDPWidget() { delete ui; }
  25. void UDPWidget::on_bind_clicked() {
  26. if (ui->bind->text() == "bind") {
  27. if (m_Socket->bind(QHostAddress(ui->localIp_2->currentText()),
  28. ui->localPort_2->value()))
  29. ui->bind->setText("unbind");
  30. else
  31. appendLog(ui->textEdit, "bind error:" + m_Socket->errorString());
  32. } else {
  33. m_Socket->abort();
  34. ui->bind->setText("bind");
  35. }
  36. }
  37. void UDPWidget::on_send_2_clicked() {
  38. QByteArray data = (ui->toHex_2->isChecked())
  39. ? QByteArray::fromHex(ui->message_2->text().toUtf8())
  40. : ui->message_2->text().toUtf8();
  41. m_Socket->writeDatagram(data, QHostAddress(ui->serverIp->text()),
  42. ui->serverPort->value());
  43. }
  44. void UDPWidget::on_clear_2_clicked() { ui->textEdit->clear(); }

运行效果

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

UDP之间通信:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/583678
推荐阅读
相关标签
  

闽ICP备14008679号