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://xiahunao.cn/news/2776984.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

微信红包测试用例设计,龙年大吉!

前言 大家好&#xff0c;我是chowley&#xff0c;在这里祝大家龙年大吉&#xff0c;身体健康&#xff0c;这次来回忆一下当时参加腾讯技术面的场景题&#xff0c;面试官让我测试拼手气红包&#xff0c;不需要考虑其他方面&#xff0c;只在功能方面进行探索。 我先贴一张红包界…

蓝桥杯每日一题------背包问题(一)

背包问题 阅读小提示&#xff1a;这篇文章稍微有点长&#xff0c;希望可以对背包问题进行系统详细的讲解&#xff0c;在看的过程中如果有任何疑问请在评论区里指出。因为篇幅过长也可以进行选择性阅读&#xff0c;读取自己想要的那一部分即可。 前言 背包问题可以看作动态规…

CSP-202203-1-未初始化警告

CSP-202203-1-未初始化警告 难点&#xff1a;时间复杂度 【核心】&#xff1a;统计输入的k组“赋值”中&#xff0c;右值不为0且未在先前作为左值出现过的次数【坑!】本题直接通过暴力枚举时间复杂度很可能过不了 【90分思路】 定义数组 initialized 用来存储已经处理过的左…

FastDFS安装并整合Openresty

FastDFS安装 一、环境--centos7二、FastDFS--tracker安装2.1.下载2.2.FastDFS安装环境2.3.安装FastDFS依赖libevent库2.4.安装libfastcommon2.5.安装 libserverframe 网络框架2.6.tracker编译安装2.7.文件安装位置介绍2.8.错误处理2.9.配置FastDFS跟踪器(Tracker)2.10.启动2.11…

猫头虎分享已解决Bug || 响应式布局错误(Responsive Design Issues):在移动设备上元素重叠、布局错位

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

windows上卸载完程序后,清理残余文件,无法删除的情况处理

现象&#xff1a;通常在卸载完软件后&#xff0c;要删除残余文件或者移动残余文件时候&#xff0c;会弹出来 原因&#xff1a; 因为文件被其他程序已经加载&#xff0c;处理的目标是找到使用这个文件的进程&#xff0c;然后kill掉。类似于linux上的lsof命令查找到进程号&…

一款全新的勒索病毒Hive来袭,已有企业中招

前言 Hive勒索病毒是一款全新的勒索病毒&#xff0c;笔者从6月26号开始关注这款全新的勒索病毒&#xff0c;知识星球相关信息&#xff0c;如下所示&#xff1a; id-ransomware网站也更新了此勒索病毒的相关信息&#xff0c;如下所示&#xff1a; 该勒索病毒采用GO语言编写&…

在线JSON解析格式化工具

在线JSON解析格式化工具 - BTool在线工具软件&#xff0c;为开发者提供方便。JSON在线可视化工具:提供JSON视图,JSON格式化视图,JSON可视化,JSON美化,JSON美化视图,JSON在线美化,JSON结构化,JSON格式化,JSON中文Unicode等等。以清晰美观的结构化视图来展示json,可伸缩折叠展示,…

OpenCV 笔记(20):霍夫圆检测

1. 霍夫圆变换 霍夫圆变换(Hough Circle Transform)是一种数字图像处理中的特征提取技术&#xff0c;用于在图像中检测圆形。它将二维图像空间中一个圆转换为该圆半径、圆心横纵坐标所确定的三维参数空间中一个点的过程。因此&#xff0c;圆周上任意三点所确定的圆&#xff0c…

【java苍穹外卖项目实战一】苍穹外卖项目介绍

文章目录 1、项目介绍1、项目概述2、 产品原型3、技术选型 1、项目介绍 在开发苍穹外卖这个项目之前&#xff0c;我们需要全方位的来介绍一下当前我们学习的这个项目。接下来&#xff0c;我们将从项目简介、产品原型、技术选型三个方面来介绍苍穹外卖这个项目。 1、项目概述 …

阿里云服务器租用价格表_2024一年_1个月_1小时收费价格表

2024年阿里云服务器租用价格表更新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、ECS u1实例2核4G、5M固定带宽、80G ESSD Entry盘优惠价格199元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月、2核4G服…

MySQL 升级脚本制作

当数据库更新字段后或添加一些基础信息&#xff0c;要对生产环境进行升级&#xff0c;之前都是手动编写sql&#xff0c;容易出错还容易缺失。 通过 Navcat 工具的数据库结构同步功能和数据同步功能完成数据库脚本的制作。 一、结构同步功能 1、选择 工具–结构同步&#xff1…

NOVATEK显示技术系列之CEDSCHPI Training差异简介

CEDS的数据封包格式&#xff1a;首先CEDS数据封包包括三个部分&#xff1a; Training Pattern即Phase1Control Data 即 Phase2RGB Data 即Phase3 Power on Timing&#xff1a; 工作原理&#xff1a; Power ON时&#xff0c;TCON会发Training Pattern&#xff0c;当COF接受Tr…

STC系列单片机的中断系统

目录 一、中断系统的定义 二、STC15系列单片机的中断请求源及结构图 三、中断查询表以及触发方式 四、在keil c中如何声明中断函数 五、外部中断 六、基于STC15芯片实战中断系统的使用 &#xff08;1&#xff09;外部中断2/外部中断3来检测门的开关状态 &#xff08;2&a…

架构之模板方法等模式的使用

目录 一、程序编写背景 二、编程思路讲解 - 类图 - 实现逻辑 - 工厂模式 - 模板方法模式 接口类&#xff08;代码&#xff09;抽象类&#xff08;代码&#xff09;具体实现类&#xff08;代码&#xff09;工厂类&#xff08;代码&#xff09;注册类&#xff08;代码&…

Vue3 常用的10个组合式 API

2024-01-025,917阅读6分钟 Vue.js是一个用于开发Web应用程序的强大JavaScript框架。Vue 2 于 2023 年 12 月 31 日停止维护。而通过Vue 3&#xff0c;组合式API增强了我们利用Vue的能力&#xff0c;使我们的代码更具模块性和可读性。下面分享10个常用的Vue3组合式API&#xff…

[office] excel如何计算毛重和皮重的时间间隔 excel计算毛重和皮重时间间隔方法 #笔记#学习方法

excel如何计算毛重和皮重的时间间隔 excel计算毛重和皮重时间间隔方法 在日常工作中经常会到用excel&#xff0c;有时需要计算毛重和皮重的时间间隔&#xff0c;具体的计算方式是什么&#xff0c;一起来了解一下吧 在日常工作中经常会到用excel&#xff0c;在整理编辑过磅数据…

美创科技与河南金融信创生态实验室签署战略合作协议

2024年1月31日&#xff0c;由普惠通科技与河南省科学院物理所、北京交通大学、中国金融电子化集团重庆金融认证中心联合发起成立中部地区第一家金融信创生态实验室运营公司&#xff08;即河南豫科普惠通信创科技有限公司&#xff09;与杭州美创科技股份有限公司战略合作签约仪式…

【python】学习笔记02-判断语句

2.1 布尔类型和比较运算符 1. 在Python中&#xff0c;可以表示真假的数据类型是&#xff1a; 布尔类型&#xff0c;字面量True表示真&#xff0c;字面量False表示假 2. 除了可以定义布尔类型外&#xff0c;还可以通过____计算得到布尔类型&#xff1f; 通过<比较运算符>…

精雕细琢的文档体验:Spring Boot 与 Knife4j 完美交汇

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 精雕细琢的文档体验&#xff1a;Spring Boot 与 Knife4j 完美交汇 前言Knife4j 与 Swagger 的区别1. 特性与优劣势对比&#xff1a;Knife4j&#xff1a;Swagger&#xff1a; 2. 选择 Knife4j 的理由&a…