【QT】手把手制作一个网络调试助手(UDP设计)

2023-05-16

TCP和UDP网络通信类的使用

Pornhub

1. 程序框架搭建

接着上一篇文章,这里就开始设计UDP的相关功能函数了,首先将其UDP的相关配置进行隐藏;

1.1 构造函数讲解


MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),ui(new Ui::MainWindow)  

其意义是执行父类QWidget的构造函数,创建一个Ui::MainWindow的类对象ui。这个UI就是Widget的private部分定义的指针变量ui。

构造函数里执行了ui->setupUi(this);相当于执行了Ui::Widget类的setupUi()函数,这个函数可以实现窗口的生成与各种属性的设置、信号与槽的关联。

析构函数则是删除new创建的指针ui。 

1.2 屏蔽UDP组件

我们希望在界面初始状态下UDP的组件不被显示出来。

    ui->txtUdpTxIP->hide();
    ui->spbUdpTxPort->hide();
    ui->cbbTxPort->hide();

1.3 声明UDP对象

在头文件中的private中申明一个UDP类的对象;

QUdpSocket *udp;

再在.cpp中进行申明;

udp = new QUdpSocket(this);

2. UI初始化准备工作

2.1 列出支持的网络通信类型

头文件public:初始化:void listNetworkType(QComboBox *cbbNetworkType);

/**
 * @brief MainWindow::listNetworkType 列出支持的网络通信类型
 * @param cbbNetworkType
 */
void MainWindow::listNetworkType(QComboBox *cbbNetworkType)
{
    QMetaEnum mtaEnum = QMetaEnum::fromType<MainWindow::NetworkType>();
    for (int i = 0; i < mtaEnum.keyCount(); i++) {
        cbbNetworkType->addItem(mtaEnum.key(i), mtaEnum.value(i));
    }
    cbbNetworkType->setCurrentText("UDP"); // 设定默认值
}

2.2 获取主机的IPV4

头文件public:初始化:QStringList getHostAddress();

/**
 * @brief MainWindow::getHostAddress 获取主机的 IPv4
 */
QStringList MainWindow::getHostAddress()
{
    QList<QHostAddress> addrList = QNetworkInterface::allAddresses();
    QStringList tmp;
    foreach (QHostAddress hostAddr, addrList){
        if(hostAddr.protocol() == QAbstractSocket::IPv4Protocol){
            if(hostAddr.toString().contains("127.0.")) continue;
            tmp<<hostAddr.toString();
        }
        else if (hostAddr.isNull())  // 主机地址为空
            continue;
    }
    return tmp;
}

2.3 UDP、TCP模式下界面修改

头文件public:初始化:void initComboBoxUDP();

void MainWindow::initComboBoxUDP()
{
    ui->lblIP->setText("本地IP");
    ui->btnLink->setText("连接");
    ui->cbbTxPort->hide();
    ui->txtUdpTxIP->show();
    ui->spbUdpTxPort->show();
}

TCPServer模式下界面修改 

void initComboBoxServer();

void initComboBoxClient();

/**
 * @brief MainWindow::initComboBoxServer 界面修改 服务器
 */
void MainWindow::initComboBoxServer()
{
    ui->lblIP->setText("本地IP");
    ui->btnLink->setText("监听");
    ui->txtUdpTxIP->hide();
    ui->spbUdpTxPort->hide();
    ui->cbbTxPort->show();
}
/**
 * @brief MainWindow::initComboBoxClient 界面修改 客户端
 */
void MainWindow::initComboBoxClient()
{
    ui->lblIP->setText("远程IP");
    ui->btnLink->setText("连接");
    ui->txtUdpTxIP->hide();
    ui->spbUdpTxPort->hide();
    ui->cbbTxPort->show();
}

2.4 UDP初始化下拉列表

头文件public:初始化:void initComboBox_Config();

/**
 * @brief MainWindow::initComboBox_Config 初始化下拉列表
 *
 */
void MainWindow::initComboBox_Config()
{
    this->listNetworkType( ui->cbbNetType );
    QStringList hostAddrList = getHostAddress();
    if( !hostAddrList.isEmpty() )
        ui->txtIP->setText( hostAddrList.at(0) );
    this->initComboBoxUDP();
}

2.5 下拉列表切换三种通信模式

/**
 * @brief MainWindow::on_cbbNetType_currentIndexChanged 切换通信模式
 * @param index
 */
void MainWindow::on_cbbNetType_currentIndexChanged(int index)
{
    switch(index){
    case TCPServer:
        this->initComboBoxServer();
        break;
    case TCPClient:
        this->initComboBoxClient();
        break;
    case UDP:
        this->initComboBoxUDP();
        break;
    }
}

2.6 连接按钮事件

获取下拉列表的值:

    enum NetworkType{
        TCPServer  = 0,
        TCPClient  = 1,
        UDP        = 2,
    };
    Q_ENUM(NetworkType)
    NetworkType networkType = (NetworkType)ui->cbbNetType->currentIndex();

列出枚举的类型,根据下拉列表读取当时的值;

然后进行判断,如果已经点击连接按键;判断下拉列表的值,如果是TCPServer则进行监听,如果是TCPClient则进行连接远端的服务器,如果是UDP则绑定端口号;

如果没有点击连接,则断开上述接口;

在头文件声明指针;

   QTcpServer *server;
    QTcpSocket *client;
    QList<QTcpSocket *>clients;
void MainWindow::on_btnLink_clicked(bool checked)
{
    NetworkType networkType = (NetworkType)ui->cbbNetType->currentIndex();

    bool ok = false;
    if(checked){
        switch(networkType){
        case TCPServer:
      //      ok = this->startListen();
            break;
        case TCPClient:
     //       ok = this->connectRemoteServer();
            break;
        case UDP:
     //       ok = this->bindAddrAndPort();
            break;
        }
        ok? ui->cbbNetType->setEnabled(false): ui->cbbNetType->setEnabled(true);
    }else{
        switch(networkType){
        case TCPServer:
      //      this->stopListen();
            break;
        case TCPClient:
     //       this->disconnectRemoteServer();
            break;
        case UDP:
      //      this->unbindAddrAndPort();
            break;
        default:break;
        }
        ui->cbbNetType->setEnabled(true);
    }
}

现在根据上述流程,将相关函数进行完善;

2.7 UDP通信

UDP每次发送数据报都要指定目标地址端口号;

QUdpSocket *udp;在头文件中声明UDP类用于实现UDP通信;

进行UDP数据接收需要使用

QUdpSocket::bid()函数绑定一个端口;用于接收传入数据报,

udp->bind( *ip, port );

获取客户端IP;获取端口号;

监听函数,返回bool值;

2.7.1 添加状态显示StatusBar

右击,选择添加状态栏;

在提升类的名称中命名为statusBar

ui->statusBar->showMessage("正在监听");

 2.7.2 定义槽函数

public slots:
    void slots_udpRxCallback();

2.7.3 插入时间戳

/**
 * @brief MainWindow::insertTimeStamp 插入时间戳前缀
 * @param tmp
 */
void MainWindow::insertTimeStamp(QString &tmp)
{
    QTime currentTime = QTime::currentTime();
    tmp.prepend( "[" + currentTime.toString("hh:mm:ss:zzz") + "]");
}

2.7.4 数据记录在RxBrowser中

/**
 * @brief MainWindow::logInRxBrowser 数据记录在RxBrowser中
 * @param ipInfo ip,port
 * @param tmp
 */
void MainWindow::logInRxBrowser(QString ipInfo, QByteArray &tmp)
{
    if(ui->ckbTimeStamp->isChecked())
        this->insertTimeStamp(ipInfo);

    QString msg;
    if( ui->ckbHexRx->isChecked() ){
        msg = tmp.toHex(' ').toUpper();
    }else{
        msg = QString::fromLocal8Bit(tmp);
    }
    ui->txtRxBrowser->append( ipInfo + msg );
}

判断;时间戳添加;

判断;转化为十六进制;

txtRxBrowser文本框输出ip信息和数据信息

2.7.5 发出信息插入服务器信息

/**
 * @brief MainWindow::insertServerInfo 插入服务器信息
 * @param tmp
 */
void MainWindow::insertTxInfo(QString &tmp)
{
    QString ip ;
    QString port;
    NetworkType networkType = (NetworkType)ui->cbbNetType->currentIndex();
    switch(networkType){
  case TCPServer :
        ip       = server->serverAddress().toString();
        port     = QString::number( server->serverPort() );
        break;
    case TCPClient:
        ip       = client->localAddress().toString();
        port     = QString::number( client->localPort() );
        break;
    case UDP:
        ip       = ui->txtIP->text();
        port     = ui->txtPort->text();
        break;
    }
    tmp.prepend( "[" + QString("Tx from %1:%2").arg(ip, port) +"]\n" );
}

2.7.6 接收插入发送端IP和端口号

/**
 * @brief MainWindow::insertRxInfo 插入发送端的IP和端口号
 * @param client
 * @param tmp
 */
void MainWindow::insertRxInfo(QNetworkDatagram *datagram, QString &tmp)
{
    QString ip = datagram->senderAddress().toString();
    QString port = QString::number( datagram->senderPort() );
    tmp.prepend( "[" + QString("Rx from %1:%2").arg(ip, port) +"]\n" );
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【QT】手把手制作一个网络调试助手(UDP设计) 的相关文章

  • UdpClient 在广播地址上接收

    在 c 中 我使用 UdpClient Receive 函数 public void StartUdpListener Object state try udpServer new UdpClient new IPEndPoint IPAd
  • Java UDP中如何获取实际数据包大小`byte[]`数组

    这是我上一个问题的后续问题 Java UDP发送 接收数据包一一接收 https stackoverflow com questions 21866382 java udp send receive packet one by one 正如
  • 从 ANDROID 2.2 发送 UDP 包(HTC 希望)

    我有一个局域网 我想从我的 android htcdesire 发送一条 udp 消息到我的电脑 它们之间有一个 WLAN 路由器 问题是 UPD 消息永远不会到达 PC Android上的代码 package org example an
  • 简单的udp代理解决方案

    我正在寻找可以代理我的 udp 数据包的解决方案 我有一个客户端向服务器发送 udp 数据包 它们之间的连接非常糟糕 导致大量数据包丢失 一种解决方案是使用一个新的代理服务器 它将所有数据包从客户端重定向到目标服务器 新的代理服务器与这两个
  • 为什么我的 UDP 广播失败?

    我正在尝试发送 UDP 广播 但wireshark 没有报告任何流量 这是执行发送的代码片段 void SendBroadcast String ip 255 255 255 255 int port 30718 String messag
  • 我应该使用哪个高级 API 来管理 iOS 上的 UDP 套接字? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 在章节 使用套接字和流 https developer apple com library mac d
  • 移动提供商无法进行 UDP 打洞

    实际上 我正在编写一个 Android 应用程序 该应用程序接收连接到 PC 的网络摄像头的图片 为了获得更多的 fps 我使用 udp 协议而不是 tcp 这个想法是 电脑将图片发送到手机的 IP 和端口 但电话提供商有不同的公共端口 所
  • 如果客户端在服务器之后启动,则 GStreamer v1.0 UDP 多播流无法正确解码

    我正在尝试使用 GStreamer 进行 UDP 多播屏幕流传输 我的投屏服务器应该在 Windows 上运行 and my 客户端应在 Linux 上运行 如果我在服务器之前启动客户端 一切都很好 问题是当我启动客户端并且服务器已经启动时
  • 用于接收 UDP 数据包的可变大小缓冲区

    我有一个 UDP 套接字 它将接收一些可能不同大小的数据包 并且我异步处理它 socket async receive from boost asio buffer buffer 65536 senderEndpoint handler 这
  • 通过 Internet 发送 UDP 数据包

    我正在尝试了解 P2P 去中心化网络的一些细节 我的问题如下 假设我有两台名为 comp1 和 comp2 的机器 现在 comp1 设置在我的家庭网络中的路由器后面 comp2 位于我的办公室中 也位于路由器后面 我是否可以像这样在 In
  • 致命错误:netinet/in.h:没有这样的文件或目录

    套接字编程 UDP 服务器 我正在尝试使用 UDP 服务器进行消息加密和解密 代码在这里 https www geeksforgeeks org message encryption decryption using udp server
  • 自 2012 年以来,WinSock 注册 IO 性能是否有所下降?

    我最近使用 MS 为该 API 提供的稍微可接受的文档编写了基于 WinSock Registered IO RIO 的 UDP 接收 最终的性能非常令人失望 单套接字性能有些稳定 约为每秒 180k 数据包 使用多个 RSS 队列 即多个
  • Rails 是否支持侦听 UDP 套接字的简洁方式?

    在 Rails 中 集成更新模型某些元素的 UDP 侦听过程的最佳方式是什么 特别是向其中一个表添加行 简单的答案似乎是在同一进程中使用 UDP 套接字对象启动一个线程 但不清楚我应该在哪里执行适合 Rails 方式的操作 有没有一种巧妙的
  • F1 2019 UDP解码

    我目前正在为 F1 方向盘开发自己的显示器 F1 2019 由codemasters提供 通过UDP发送数据 该数据存储在字节数组中 我在解码返回的数组时遇到一些问题 问题是我得到了很多信息 但我不知道如何处理它们 我将向您介绍我所尝试过的
  • 在 PowerShell 中通过 UDP 发送和接收数据

    我正在尝试编写一个脚本来使用 PowerShell 进行测试和应用 测试应包括通过 UDP 向远程服务器发送字符串 然后读取该服务器的响应并对结果执行某些操作 我需要的唯一帮助是脚本的中间两个步骤 发送字符串 然后 接收响应 在端口 UDP
  • P2P网络游戏/应用程序:类似“战网”匹配服务器的不错选择

    我正在制作一个网络游戏 1v1 游戏中是 p2p 不需要游戏服务器 然而 为了让玩家能够 找到彼此 而不需要在另一种媒介中协调并输入IP地址 类似于网络游戏的现代时代 我需要有一个协调 匹配服务器 我无法使用常规网络托管 因为 客户端将使用
  • 为什么 Kademlia 使用 UDP?

    为什么Kademlia 分布式哈希表 http en wikipedia org wiki Kademlia使用 UDP 作为其网络传输协议 即使它不可靠 主要原因是您快速查询了许多以前从未建立过联系并且可能在查找过程中永远不会再看到的节点
  • 如何读取 UDP 连接直至超时?

    我需要读取 UDP 流量 直到超时 我可以通过在 UDPConn 上调用 SetDeadline 并循环直到出现 I O 超时错误来做到这一点 但这看起来很黑客 基于错误条件的流量控制 下面的代码片段看起来更正确 但并没有终止 在生产中 这
  • 如何从 DatagramPacket 中检索字符串[重复]

    这个问题在这里已经有答案了 下面的代码打印 B 40545a60 B 40545a60abc exp 但我想打印abc 以便我可以从接收系统检索正确的消息 public class Operation InetAddress ip Data
  • RTSP 设置后接收 RTP 数据包

    我正在尝试使用 Python 从 IP 摄像机流式传输 RTP 数据包 我能够使用 RTSP 协议发送描述 设置和播放命令 但是 我无法开始使用 RTP 传输实际视频流 这是代码 import socket def printrec rec

随机推荐

  • GPU渲染管线之旅|08 Pixel Shader

    在这一部分中 xff0c 我们来谈谈像素处理的前半部分 dispatch和实际的像素着色 事实上 xff0c 这部分是大多数图形开发者在谈到PS stage时所关心的内容 有关alpha blend和Late Z的内容则会下一篇文章中去探讨
  • MFC基于CSplitterWnd类的多窗口分割

    使用平台 xff1a win7 64bit 使用环境 xff1a VS2012 1 CSplitterWnd介绍 上图是从MSDN中截取的类的继承图表 xff0c CSplitterWnd类继承自CWnd类 这个类主要就是提供窗口分割的功能
  • OpenCV - 区域生长算法

    1 理论基础 区域生长算法的基本思想是将有相似性质的像素点合并到一起 对每一个区域要先指定一个种子点作为生长的起点 xff0c 然后将种子点周围领域的像素点和种子点进行对比 xff0c 将具有相似性质的点合并起来继续向外生长 xff0c 直
  • 不规则Contours内部像素的操作

    在findContours函数使用了之后 xff0c 有时候就会面临对Contours内部区域的访问 由于contours不一定是凸图形 xff0c 所以使用循环操作的时候总感觉不那么方便 比如在下图中 xff0c 已经使用findCont
  • ros代码中添加使用opencv库,cv::Mat和ros image之间的相互转换

    https blog csdn net sunyoop article details 78630024 ros中很多时候要用到图形处理 xff0c 这时就需要使用opencv库 xff0c 本篇主要将怎么在ros现成node上使用open
  • Ubuntu 16.04 使用

    这篇博客用来专门记录尝试搬迁工作环境到Linux下的使用笔记 xff0c 主要包含有常用软件的安装 xff0c 配置 1 安装输入法 ubuntu 16 04中支持ibus输入系统 1 系统 gt 首选项 gt IBus设置 在弹出的IBu
  • 牛顿迭代法求解方程

    说明 xff1a 该篇博客源于博主的早些时候的一个csdn博客中的一篇 xff0c 由于近期使用到了 xff0c 所以再次作一总结 原文地址 概述 牛顿迭代法 xff08 Newton s method xff09 又称为牛顿 拉夫逊 xf
  • OpenCV - 均值迭代分割

    题外话 之前在博客中写过一篇 区域生长 的博客 xff0c 区域生长在平时经常用到 xff0c 也比较容易理解和代码实现 xff0c 所以在很多情况下大家会选择这种方法 但是区域生长有一个最致命的点就是需要选取一个生长的种子点 为了交流学习
  • IMU原理及姿态融合算法详解

    IMU原理及姿态融合算法详解 一 组成 IMU全称是惯性导航系统 xff0c 主要元件有陀螺仪 加速度计和磁力计 其中陀螺仪可以得到各个轴的加速度 xff0c 而加速度计能得到x xff0c y xff0c z方向的加速度 xff0c 而磁
  • FrankMocap win10安装指导

    本文是相当于将github上frankmocap的安装指导进行了翻译 xff0c 增加了一下windows下安装遇到的坑以及注意事项 如果是linux系统应该安装官方的安装指导安装就可以 xff0c 可以直接参考官方安装指导 安装所有模块
  • ADRC学习(1)系统在调节过程中安排过渡过程的作用

    1 二阶系统的调节过程 考虑对于如下所示的二阶系统 x
  • 笔记本更换SSD后卡顿、假死、失去响应问题探究

    某些笔记本电脑将HDD更换为SSD后 xff0c 系统运行过程中会随机产生半分钟到一分钟的卡顿 xff08 假死 xff09 期间鼠标指针可以运动 xff0c 但所有程序均失去响应 xff0c 也无法打开新的程序 HDD硬盘指示灯常亮 xf
  • 机器人 齐次变换矩阵 位姿变换矩阵(RT矩阵) Matlab参数公式计算

    对于齐次位姿变换 xff08 RT矩阵 xff09 xff0c 有的时候手动计算公式参数太多比较麻烦 xff0c 因此利用matlab参量syms xff0c 可以方便一些 xff0c 可以用于计算机器人正运动学位姿矩阵的参数表示 xff0
  • UART串口校验方式(无校验、奇偶校验、固定校验)

    UART串口校验方式 xff08 奇偶校验 固定校验 无校验 xff09 串口通信校验方式奇偶校验位固定校验位 Stick 无校验位 校验位 xff1a 串口通信中的检错方式 串口在接收数据时 xff0c 如果无检验位 xff0c 则只要检
  • 更改LXDE的语言为中文

    之前给旧笔记本安装了Debian8 43 LXDE嘛 xff0c 运行比较流畅 安装过程中本想选择中文的 xff0c 但是安装界面中旧有中文乱码 xff0c 所以还是选了英语 等装好了系统 xff0c 把apt update 43 upgr
  • 干掉Nouveau安装Linux Nvidia显卡驱动

    https blog csdn net misiter article details 7652731 干掉Nouveau安装Linux Nvidia显卡驱动 首先说明下什么是Nouveau xff0c 为什么有些系统安装N卡驱动的时候会提
  • 【C应用】红外遥控小车程序分析(上)——四轮马达方向控制程序分析

    目录 驱动原理分析 L293D功能分析 代码分析 驱动原理分析 小车采用两片L293D芯片控制四个车轮 xff0c 原理图如下 xff1a 因为L293D可分别控制两路电机 xff0c 为了方便理解L293D芯片的工作原理 xff0c 拿L
  • 【RTOS】RTOS实时操作系统随笔(结合UCOSII相关移植)

    目录 无操作系统下的程序结构及缺陷 有操作系统下的解决方案及CPU工作原理 操作系统调度策略及时间片轮转策略 操作系统TICK及进程切换 UCOSII介绍 UCOSII进程任务切换原理 xff1a UCOS进程的堆栈 xff1a 时钟TIC
  • 【STM32CobeMX】CubeMX建立基于STM32F1VBT6的FreeRTOS

    STM32F103VBT6 内部时钟源RCC 如果使用RTOS 使用了RTOS xff0c 默认使用SysTick xff1b 所以HAL库的时基就要用其他的定时器 当用了RTOS xff0c 就要设置HAL的timebase为其他Time
  • 【QT】手把手制作一个网络调试助手(UDP设计)

    TCP和UDP网络通信类的使用 Porn hub 1 程序框架搭建 接着上一篇文章 xff0c 这里就开始设计UDP的相关功能函数了 xff0c 首先将其UDP的相关配置进行隐藏 xff1b 1 1 构造函数讲解 MainWindow Ma