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.rhkb.cn/news/255021.html

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

相关文章

Linux文件和目录管理

目录基础 Linux操作系统以目录的方式来组织和管理系统中的所有文件。所谓的目录&#xff0c;就是将所有文件的说明信息采用树状结构组织起来。每个目录节点之下会有文件和子目录。 所有一切都从 ‘根’ 开始&#xff0c;用 ‘/’ 代表, 并且延伸到子目录。 bin&#xff1a;B…

【RT-DETR有效改进】利用SENetV1重构化网络结构 (ILSVRC冠军得主)

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 本文给大家带来的改进机制是SENet(Squeeze-and-Excitation Networks)其是一种通过调整卷积网络中的通道关系来提升性能的网络结构。SENet并不是一个独立的网络模型,而是一个可以和现有的任何一个模型相结合…

R语言学习case10:ggplot基础画图Parallel Coordinate Plot 平行坐标图

step1: 导入ggplot2库文件 library(ggplot2)step2&#xff1a;带入自带的iris数据集 iris <- datasets::irisstep3&#xff1a;查看数据信息 dim(iris)维度为 [150,5] head(iris)查看数据前6行的信息 step4&#xff1a;利用ggplot工具包绘图 plot5 <- ggparcoord(…

【ArcGIS微课1000例】0101:删除冗余节点或折点

文章目录 一、实验描述二、实验数据三、实验过程1. 手动删除2. 简化线工具四、注意事项一、实验描述 矢量数据获取通常来源于手动或者ArcScan自动采集,其基本存储方式就是记录每个要素的点坐标,如点要素就是一个坐标、线要素由多个点要素连接形成。当某段线要素被过多的节点…

单片机学习笔记---蜂鸣器工作原理

目录 蜂鸣器介绍 蜂鸣器的驱动方式 ULN2003D芯片工作原理 实战预备知识&#xff1a;基础乐理 音名的分组 全音和半音的关系 音高的表示 五线谱中的符号定义 简谱上的符号定义 C调音符与频率对照表 相关计算 蜂鸣器介绍 蜂鸣器是一种将电信号转换为声音信号的器件&a…

SaperaCamExpert(相机专家)中文使用指南

参考&#xff1a;SaperaCamExpert中文使用指南.PDF 文章目录 软件介绍安装首次打开资源占用率功能主界面布局菜单栏FileViewPre-Processing&#xff1a;预处理 Tools&#xff1a; 快捷键&#xff1a;新建&#xff1b;打开&#xff1b;保存&#xff1b;帮助Device窗体属性树图像…

Bytebase 签约 Vianova,助力欧洲城市交通智能平台中 Snowflake 和 PG 的变更自动化及版本控制

在数字化发展的浪潮中&#xff0c;自动化数据库变更管理成为提升产品上线效率、降低人为失误风险的关键工具&#xff0c;同时促进流程的一致性与标准化&#xff0c;确保合规性和变更的可追溯性。近日&#xff0c;数据库 DevOps 团队协同管理工具 Bytebase 签约欧洲交通数据管理…

网站被攻击有什么办法呢?

最近&#xff0c;德迅云安全遇到不少网站用户遇到攻击问题&#xff0c;来咨询安全解决方案。目前在所有的网络攻击方式中&#xff0c;DDoS是最常见&#xff0c;也是最高频的攻击方式之一。不少用户网站上线后&#xff0c;经常会遭受到攻击的困扰。有些攻击持续时间比较短影响较…

股票均线的使用方法和实战技术,看涨看空的均线形态与案例教学

一、教程描述 本套教程讲解了14种均线的特殊形态&#xff0c;通过直观图形以及大量案例的教学&#xff0c;将深奥、繁琐的均线变得生动与具体&#xff0c;广大投资者在认真学习以后&#xff0c;可以学会均线的使用方法&#xff0c;掌握最强的均线应用实战技术。本套教程不仅适…

Electron+Vue实现仿网易云音乐实战

前言 这个项目是我跟着官方文档的那个Electron入门教程大致跑了一遍,了解了下Electron开发流程之后的实战项目,所以中间应该是会有很多写法不是很规范,安全性有可能也没考虑到,可实现的各种api也不是很了解,适合初学者。 必须感谢 https://github.com/Binaryify/NeteaseC…

Postman接口与压力测试实例

Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。它提供功能强大的 Web API & HTTP 请求调试。 1、环境变量和全局变量设置 环境变量可以使用在以下地方&#xff1a; URLURL paramsHeader valuesform-data/url-encoded valuesRaw body contentHelper fi…

工信部颁发的《计算机视觉处理设计开发工程师》中级证书

计算机视觉&#xff08;Computer Vision&#xff09;是一门研究如何让计算机能够理解和分析数字图像或视频的学科。简单来说&#xff0c;计算机视觉的目标是让计算机能够像人类一样对视觉信息进行处理和理解。为实现这个目标&#xff0c;计算机视觉结合了图像处理、机器学习、模…

[VulnHub靶机渗透] Misdirection: 1

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…

关于数字图像处理考试

我们学校这门科目是半学期就完结哦&#xff0c;同学们学习的时候要注意时间哦。 选择题不用管&#xff0c;到时候会有各种版本的复习资料的。 以下这些东西可能会是大题的重点&#xff1a; 我根据平时代码总结的&#xff0c;供参考 基本操作&#xff1a; 1.读图&#xff1a;…

HTTP和HTTPS区别!

http 是我们几乎天天都要打交道的东西&#xff0c;相关知识点有点多&#xff0c;所以也有不少面试必问的点&#xff0c;这里做了一些整理&#xff0c;帮且大家树立完整的 http 知识体系&#xff0c;对面试官说 so easy HTTP 的特点和缺点 特点&#xff1a;无连接、无状态、灵…

【Git版本控制 01】基本操作

目录 一、初始配置 二、添加文件 三、查看日志 四、修改文件 五、版本回退 六、撤销修改 七、删除文件 一、初始配置 Git版本控制器&#xff1a;记录每次的修改以及版本迭代的一个管理系统。 # 初始化本地仓库&#xff1a;git init(base) [rootlocalhost gitcode]# gi…

房屋租赁系统的Java实战开发之旅

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

【C语言期末】商品管理系统

本文资源&#xff1a;https://download.csdn.net/download/weixin_47040861/88820155 1.题目要求 商品管理系统 商品信息包括&#xff1a;包括编号、类别、名称、价格、折扣比例、生产时间 、存货数量等要求&#xff1a;1、信息首先保存在文件中&#xff0c;然后打开文件进行…

用友U8 Cloud ReportDetailDataQuery SQL注入漏洞复现(QVD-2023-47860)

0x01 产品简介 用友U8 Cloud 提供企业级云ERP整体解决方案,全面支持多组织业务协同,实现企业互联网资源连接。 U8 Cloud 亦是亚太地区成长型企业最广泛采用的云解决方案。 0x02 漏洞概述 用友U8 cloud ReportDetailDataQuery 接口处存在SQL注入漏洞,攻击者未经授权可以访…

C语言----内存函数

内存函数主要用于动态分配和管理内存&#xff0c;它直接从指针的方位上进行操作&#xff0c;可以实现字节单位的操作。 其包含的头文件都是&#xff1a;string.h memcpy copy block of memory的缩写----拷贝内存块 格式&#xff1a; void *memcpy(void *dest, const void …