Qt项目(2)Qt实现网络调试助手(上)

在这里插入图片描述

前言

所谓网络调试助手,即软件同时支持UDP协议和TCP协议。就是可以使用UDP协议,监听端口,完成与对端设备的数据收发。同时使用TCP协议,既可以当作服务器端,监听本机主机端口,得到客户端连接信息,并管理与客户端之间的连接,可完成数据的收发;又可以当作TCP客户端,发送连接请求与远端服务器连接,可以向服务器发送数据进行请求,也能够接收到服务器给予的应答。这是网口助手最基本的功能。本文分成两篇完成。

1.tcp服务器

1.1简介TCP

TCP协议,传输控制协议,是一个用于数据传输的底层的网络协议,多个互联网协议包括FTP,HTTP协议都是基于TCP协议的。TCP是一个面向数据流和连接的可靠的传输协议。QTcpSocket类为TCP提供了一个接口,可以用其实现POP3、SMTP等标准的网络协议,也可以实现自定义的网络协议。连接的一端是客户端,另一端是服务器端,也就是C/S模型。

1.2步骤与目标

使用Qt network做一个TCP服务器,可以接收客户端的访问请求,能够传输数据。 首先创建QTcpServer类对象,用于管理服务器;调用listen方法,监听对应地址对应端口,使本主机作为服务器,使得程序能够监听某一端口的连接情况;当有客户端发出连接请求时,服务器对象会发出newConnection()信号,监听过程出错时,服务器会发出acceptError()信号;连接建立后出现错误会发出disconnected()信号,有数据来临会发出readyread()信号,当需要发送数据到客户端的时候,调用write方法即可。

1.3效果

与网口助手调试(链接在文末)结果如下,收发数据正常。
在这里插入图片描述
与Qt开发客户端测试结果如下,汉字收发正常。
在这里插入图片描述

1.4代码

main文件

#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpserver>
#include <QNetworkInterface>
#include <QTcpSocket>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void doProcessNewConnection();
    void doProcessAcceptError(QAbstractSocket::SocketError);
    void doProcessDisconnected();
    void doProcessReadyRead();
//    void doProcessConnect();
    void on_band_Btn_clicked();
    void on_tran_Btn_clicked();
private:
    Ui::MainWindow *ui;
    QTcpServer *myServer;
    QTcpSocket *client;
    QList<QTcpSocket *>arrayClient;
    void Init();
};
#endif // MAINWINDOW_H

.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

#define MAXNUM 100

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::Init()
{
    myServer = new QTcpServer(this);
    this->setWindowTitle("服务器");
}
//绑定按钮槽函数
void MainWindow::on_band_Btn_clicked()
{
    //方法1 :通过程序遍历网卡ip
//    QList<QHostAddress>addrs = QNetworkInterface::allAddresses();
//    for (int i = 0; i <addrs.length(); ++i) {
//        QHostAddress addr = addrs.at(i);
//        qDebug()<<addr.toString();
//        if(addr.toString().contains("192.")){
//            myAddr = addr.toString();
//            break;
//        }
//    }
    //方法2: 手动设置ip
    QString myAddr = ui->serverIP->text();
    QString myPort = ui->serverPort->text();
    QString msg;
    bool ret = myServer->listen(QHostAddress(myAddr),myPort.toUInt());//监听对应地址对应端口,使本主机作为服务器
    if(!ret){
        msg = "绑定失败!";
    }
    else{
        msg = "绑定成功!";
        ui->band_Btn->setEnabled(false);
    }
    ui->textEdit->append(msg);

    myServer->setMaxPendingConnections(MAXNUM);//设置等待连接队列中的最大数量,默认30
    connect(myServer,SIGNAL(newConnection()),this,SLOT(doProcessNewConnection()));//监听之后,新的客户端接入会触发此信号
    connect(myServer,SIGNAL(acceptError(QAbstractSocket::SocketError)),
            this,SLOT(doProcessAcceptError(QAbstractSocket::SocketError)));//监听过程出错会进入这个槽

}
//绑定发送按钮槽函数
void MainWindow::on_tran_Btn_clicked()
{
    //获取界面ip地址和端口信息
    QString ip = ui->clientIP->text();
    QString port = ui->clientPort->text();
    //查找对应的客户
    for (int i = 0; i < arrayClient.length(); ++i) {
        if(arrayClient.at(i)->peerAddress().toString() == ip){//找到对应的ip
            if(arrayClient.at(i)->peerPort() == port.toUInt()){//找到对应端口
                QString msg = ui->textEdit_2->toPlainText();
                arrayClient.at(i)->write(msg.toUtf8());//使用utf8可以发送汉字,对方也使用utf8则可以正确接收
                ui->textEdit_2->clear();
                break;
            }
        }
    }
}
void MainWindow::doProcessNewConnection()
{
  client =  myServer->nextPendingConnection();//建立连接,获取客户端对象
  QString msg = QString("客户端[%1:%2] 连入!").arg(client->peerAddress().toString()).arg(client->peerPort());
  ui->textEdit->append(msg);
  arrayClient.append(client);//存储已接入的客户端
  //客户端断开
connect(client,SIGNAL(disconnected()),this,SLOT(doProcessDisconnected()));//建立间接之后,监听断开信号
  //读取内容
connect(client,SIGNAL(readyRead()),this,SLOT(doProcessReadyRead()));//准备接收数据
}
void MainWindow::doProcessAcceptError(QAbstractSocket::SocketError err)
{
    qDebug()<<err;
}
void MainWindow::doProcessDisconnected()
{
    QTcpSocket *client = (QTcpSocket *)this->sender();
    QString msg = QString("客户端[%1:%2] 退出!").arg(client->peerAddress().toString()).arg(client->peerPort());
    ui->textEdit->append(msg);
    //删除客户端列表断开的客户端
    for (int i = 0; i < arrayClient.length(); ++i) {
        if(arrayClient.at(i)->peerAddress() == client->peerAddress()){
            if(arrayClient.at(i)->peerPort() == client->peerPort()){
                arrayClient.removeAt(i);
            }
        }
    }
}
void MainWindow::doProcessReadyRead()
{
    QTcpSocket *client = (QTcpSocket *)this->sender();
    QString str1 = QString("客户端[%1:%2] 说:").arg(client->peerAddress().toString()).arg(client->peerPort());//返回客户端的ip与port
    QString msg;
    QString str2;
    while(!client->atEnd()){
        msg.append(QString(client->readAll()));//接收数据
    }
    str2 = QString("%1%2").arg(str1).arg(msg);
    ui->textEdit->append(str2);
}

2.Tcp客户端

使用Qt开发Tcp客户端与服务器之间的差异很小,主要是服务器使用的类对象是由QTcpServer实例化的,而客户端的类对象是由QTcpSocket实例化的。另外一点就是客户端,连接服务器时要用到,connectToHost()方法,服务器则是要用listen监听某个端口。当连接建立之后,对于连接的管理,数据的处理几乎连信号都是一样的。

2.1效果

与网口调试助手测试收发数据正常
在这里插入图片描述
与Qt开发服务器测试收发数据正常。
在这里插入图片描述

2.2代码

main文件

#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void on_btn_Connect_clicked();
    void doProcessConnected();
    void doProcessReadyRead();
    void doProcessDisconnected();
    void doProcessError(QAbstractSocket::SocketError);
    void on_btn_Send_clicked();
private:
    Ui::MainWindow *ui;
    QTcpSocket *myClient;
    void Init();
};
#endif // MAINWINDOW_H

.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Init();
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::Init(){
    this->setWindowTitle("客户端");
    myClient = new QTcpSocket(this);
}
void MainWindow::on_btn_Connect_clicked()
{
    QString servIP = ui->serverIP->text();//获取用户的ip
    QString servPort = ui->serverPort->text();//获取用户的端口
    myClient->connectToHost(QHostAddress(servIP),servPort.toUInt());//连接服务器
    connect(myClient,SIGNAL(connected()),this,SLOT(doProcessConnected()));//连接成功
    connect(myClient,SIGNAL(readyRead()),this,SLOT(doProcessReadyRead()));//获取数据
    connect(myClient,SIGNAL(disconnected()),this,SLOT(doProcessDisconnected()));//连接断开
    connect(myClient,SIGNAL(error(QAbstractSocket::SocketError))
           ,this,SLOT(doProcessError(QAbstractSocket::SocketError)));//连接出错
}
//连接建立信号
void MainWindow::doProcessConnected()
{
    QString msg = "服务器连接成功!";
    ui->textEdit->append(msg);
    ui->btn_Connect->setEnabled(false);
}
void MainWindow::doProcessReadyRead()
{
    QString msg,str1,str2;
    str1 = QString("服务器[%1 %2]说:").arg(myClient->peerAddress().toString()).arg(myClient->peerPort());
    while (!myClient->atEnd()) {
        str2.append(QString(myClient->readAll()));//接收数据
    }
    msg = QString("%1%2").arg(str1).arg(str2);
    ui->textEdit->append(msg);
}
void MainWindow::doProcessDisconnected()
{
    QString msg = "服务器退出!";
    ui->textEdit->append(msg);
    ui->btn_Connect->setEnabled(true);
}
void MainWindow::doProcessError(QAbstractSocket::SocketError err)
{
    qDebug()<<err;
    qDebug()<<myClient->errorString();
}
//发送数据
void MainWindow::on_btn_Send_clicked()
{
    QString msg = ui->textEdit_2->toPlainText();
    int ret = myClient->write(msg.toUtf8());
    qDebug()<<ret;
    if(ret <=0){
        return;
    }
    ui->textEdit_2->clear();
}

3.传送门

END

🎏文章原创,首发于CSDN论坛。
🎏欢迎点赞❤❤收藏⭐⭐打赏💴💴!
🎏欢迎评论区或私信指出错误❌,提出宝贵意见或疑问❓。


  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: QT网络调试助手是一款基于QT平台开发的网络调试工具。它的主要功能是辅助开发人员进行网络调试工作,能够对HTTP、TCPUDP、WebSocket等协议进行解析和分析,提供可视化的界面展示,便于开发人员快速定位和解决问题。 QT网络调试助手具有以下几个主要特点: 1. 集成多种协议支持:QT网络调试助手支持HTTP、TCPUDP、WebSocket等多种协议,能够解析协议包,展示数据信息。通过这些数据信息,可以快速定位和解决网络开发中出现的各种问题。 2. 监听端口支持:QT网络调试助手还支持监听指定端口,能够实时获取网络数据流,方便进行数据分析。同时,它还提供了响应数据修改的功能,可以在不影响源数据的情况下,对数据进行调整和修改。 3. 界面友好:QT网络调试助手提供了直观、友好的界面,包含请求列表、响应列表、WebSocket列表等多种显示模式,以及自定义筛选条件,让开发人员可以更加方便地操作和查看数据信息。 4. 精简实用:QT网络调试助手的设计十分精简实用,针对网络调试的核心需求进行了精心设计,避免了繁琐的操作过程和不必要的功能干扰。 总之,QT网络调试助手是一个功能强大、易于操作、界面友好的网络调试工具,可以帮助开发人员快速发现和解决网络开发中出现的各种问题。 ### 回答2: Qt网络调试助手是一款基于Qt框架开发的网络调试工具,它可以帮助开发人员在网络通信过程中对报文进行捕获、分析和调试Qt网络调试助手主要包括以下几个功能: 1. 报文捕获功能:Qt网络调试助手可以捕获网络通信过程中的请求报文和响应报文,并以可视化的方式展示出来。这对于开发人员来说非常重要,因为它可以帮助他们快速找到报文中的问题。 2. 报文分析功能:Qt网络调试助手可以对捕获的报文进行分析,包括解析HTTP协议、分析应用层协议等。开发人员可以通过这个功能更深入地了解网络通信的过程,更快地解决问题。 3. 报文编辑功能:Qt网络调试助手还可以对捕获的报文进行编辑,包括修改请求参数、请求头、响应参数、响应头等。这对于开发人员进行网络调试非常方便。 4. 报文保存功能:Qt网络调试助手还可以将捕获的报文保存到本地文件中,以便于之后的查看和分析。 总体来说,Qt网络调试助手是一款非常实用的网络调试工具,它为开发人员提供了捕获、分析、编辑和保存网络报文的功能,让开发人员更快地找到网络通信中的问题,并解决它们。同时它也是一款开源工具,可以帮助开源社区的发展。 ### 回答3: Qt网络调试助手是一款功能强大的网络调试工具。它能够帮助开发者快速识别和解决网络问题,是一个必备的调试工具。 Qt网络调试助手具有以下主要特点: 1. 支持多个网络协议 Qt网络调试助手支持常见的网络协议,如HTTP/HTTPS、TCP/UDP、WebSocket等。可以轻松地在这些协议之间进行切换,并查看它们的详细信息。 2. 支持数据的查看和编辑 在调试过程中,开发者可以实时查看请求和响应的数据,同时也可以编辑这些数据来模拟各种情况。 3. 支持数据的保存和发送 Qt网络调试助手也支持将数据保存到本地,以便后续分析。同时还可以发送数据到指定的地址,以便测试网络性能和稳定性。 4. 支持用户名和密码的验证 如果需要验证用户名和密码,Qt网络调试助手也可以轻松地完成验证过程。这非常有用,减少了开发人员的负担。 总之,Qt网络调试助手是一款十分实用的网络调试工具。它可以帮助开发人员快速定位和解决网络问题,提高工作效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGA小油条

原创不易,请多支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值