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_OBJECTpublic: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");} elseappendLog(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_OBJECTpublic: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");elseappendLog(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之间通信:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/674587.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

注意啦,MySQL8.0最新版是没有utf8选项,但是有utf8mb3和utf8mb4选项

今天在安装完MySQL最新版&#xff08;8.0.36&#xff09;&#xff0c;然后用navicat连接数据&#xff0c;创建数据库的时候&#xff0c;发现: MySQL最新版是没有utf8选项&#xff0c;但是有utf8mb3和utf8mb4选项 然后就只能卸载掉最新版&#xff0c;安装了8.0.28. &#xff08…

一文学会Axios的使用

异步请求 同步发送请求过程如下 浏览器页面在发送请求给服务器&#xff0c;在服务器处理请求的过程中&#xff0c;浏览器页面不能做其他的操作。只能等到服务器响应结束后才能&#xff0c;浏览器页面才能继续做其他的操作。 异步发送请求过程如下浏览器页面发送请求给服务器&…

JavaScript 跨窗口通信(Cross-Window Communication)

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 在现代 Web 开发中&#xff0c;跨窗口通信是一种常见需求。它允许在…

服务器和云计算之间有什么关系?

云计算与服务器之间的关系是密切而复杂的。首先&#xff0c;我们需要明确一点&#xff0c;云计算并不是一种全新的技术&#xff0c;而是对现有技术的一种整合和改进。在这个基础上&#xff0c;我们可以更好地理解云计算与服务器之间的关系。 服务器是云计算的重要组成部分之一…

如何在Linux上部署1Panel运维管理面板并实现无公网ip远程访问

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

Python中使用opencv-python库进行颜色检测

Python中使用opencv-python库进行颜色检测 之前写过一篇VC中使用OpenCV进行颜色检测的博文&#xff0c;当然使用opencv-python库也可以实现。 在Python中使用opencv-python库进行颜色检测非常简单&#xff0c;首选读取一张彩色图像&#xff0c;并调用函数imgHSV cv2.cvtColor…

华为 Huawei 交换机 黑洞MAC地址的作用和配置示例

黑洞mac作用&#xff1a;某交换机上配置某个PC的mac地址为黑洞mac&#xff0c;那么这台PC发出来的包都会被交换机丢弃&#xff0c;不会被转发到网络中。 组网需求&#xff1a; 如 图 2-13 所示&#xff0c;交换机 Switch 收到一个非法用户的访问&#xff0c;非法用户的 MAC 地址…

C++新版本特性

目录: 前言 C11的常用新特性 auto类型推导&#xff1a; auto的限制&#xff1a; auto的应用&#xff1a; decltype类型推导&#xff1a; decltype的实际应用&#xff1a; 使用using 定义别名&#xff1a; 支持函数模板的默认模板参数 : tuple元组&#xff1a; 列表初…

每日OJ题_位运算①_位运算解题方法+3道OJ

目录 位运算算法原理 ①力扣191. 位1的个数 解析代码 ②力扣338. 比特位计数 解析代码 ③力扣461. 汉明距离 解析代码 位运算算法原理 常见位运算解题方法&#xff1a; 1. 基础位运算&#xff1a; &&#xff1a;按位与&#xff0c;有0就是0 | &#xff1a;按位或&a…

C++分支语句

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 大家新年快乐&#xff0c;今天&#xff0c;我们来了解一下分支语句。 文章目录 1.什么是分支语句 1.if语句 基本形式 用法说明 练习 2.if-else语句 基本形式 用法说明 练习 3.switch语句 基本形式…

LeetCode 热题 100 | 链表(中下)

目录 1 19. 删除链表的倒数第 N 个节点 2 24. 两两交换链表中的节点 3 25. K 个一组翻转链表 4 138. 随机链表的复制 菜鸟做题第三周&#xff0c;语言是 C 1 19. 删除链表的倒数第 N 个节点 到底是节点还是结点。。。 解题思路&#xff1a; 设置双指针 left 和 ri…

云安全的基本概念(基本目标与指导方针)

目录 一、云安全概念概述 1.1 概述 二、云安全的基本目标 2.1 安全策略开发模型 2.1.1 信息安全三元组 2.1.1.1 保密性(Confidentiality) 2.1.1.2 完整性(Integrity) 2.1.1.3 可用性(Availability) 2.1.2 信息安全三元组的局限性 2.2 其他信息安全属性 2.2.1 真实性 …

Java基础知识练习题

1.对Java源文件进行编译操作的命令是&#xff08;B&#xff09; A.Java B.javac C.where is java D.javaw 2.下列命令中&#xff0c;用来运行Java程序的是&#xff08;A&#xff09;A.java B. javadoc C. jar D. javac 分析&#xff1a; 对Java源程序进行编译的命令是J…

踩坑实录(Third Day)

临近年关&#xff0c;同事们该回家的也都回家了&#xff0c;所以我对工作的欲望不是很强烈&#xff0c;所以就主要是自己学习了一下&#xff0c;在 B 站看看视频&#xff0c;自己敲代码&#xff0c;所以今天没遇到什么坑&#xff0c;但是可以分享一下之前踩到的两个坑。 此为第…

电商小程序04实现登录逻辑

目录 1 创建自定义方法2 获取用户名和密码3 验证用户是否同意协议4 验证用户名和密码总结 上一篇我们实现了登录功能的前端界面&#xff0c;这一篇实现一下登录的具体逻辑。 1 创建自定义方法 一般如果页面点击按钮需要有事件响应的&#xff0c;我们用自定义方法来实现。打开我…

第四篇:数据库安装(命令行)

数据库命令行界面安装 mysql官网&#xff0c;下载解压 https://dev.mysql.com/downloads/mysql/ 在安装之前先去检查一下,本地计算机的用户合组 winr(输入lusrmgr.msc) -点击组-双击administrator 如果只有这两个,那么就添加一下,提高网络服务的权限(避免出现mysql启动失败) …

MySQL之体系结构

华子目录 MySQL简介MySQL的特性MySQL版本MySQL常见版本 数据库排名网站MySQL结构体系查看最大连接数查询缓存配置情况 一条SQL语句执行流程 MySQL简介 MySQL是一个小型关系数据库管理系统&#xff0c;开发者为瑞典MySQL AB公司。在2008年1月16号被sun公司10亿美金收购。2009年…

springboot项目启动报错:dynamic-datasource can not find primary datasource

项目启动报错信息 Caused by: com.baomidou.dynamic.datasource.exception.CannotFindDataSourceException: dynamic-datasource can not find primary datasourceat com.baomidou.dynamic.datasource.DynamicRoutingDataSource.determinePrimaryDataSource(DynamicRoutingDat…

编程实例分享,手表养护维修软件钟表维修开单管理系统教程

编程实例分享&#xff0c;手表养护维修软件钟表维修开单管理系统教程 一、前言 以下教程以 佳易王钟表维护维修管理系统软件V16.0为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 左侧为导航栏&#xff0c; 1、系统设置&#xff1a;可以设置打…

【深度学习】pytorch 与 PyG 安装(pip安装)

【深度学习】pytorch 与 PyG 安装&#xff08;pip安装&#xff09; 一、PyTorch安装和配置&#xff08;一&#xff09;、安装 CUDA&#xff08;二&#xff09;、安装torch、torchvision、torchaudio三个组件&#xff08;1&#xff09;下载镜像文件&#xff08;2&#xff09;创建…