QT 实现仿制 网络调试器(未实现连接唯一性) QT5.12.3环境 C++实现

网络调试助手:


提前准备:在编写代码前,要在.pro工程文件中,添加network模块。


服务端:

代码:

widget.h
cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtWidgets>
#include <QTcpServer> // 监听套接字
#include <QTcpSocket> // 通讯套接字
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_start_button_clicked(); // 启动按钮slot
    void new_connection_slot(); // 连接slot
    void ready_read_slot(); // 可读slot
    void on_send_button_clicked(); // 发送按钮slot

private:
    Ui::Widget *ui;
    QTcpServer *tcp_server; // 服务端
    QTcpSocket *tcp_socket; // socket
};

#endif // WIDGET_H
widget.cpp
cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("网络调试器服务端"); // 标题


    // 实例化监听套接字
    tcp_server = new QTcpServer(this);
    tcp_socket = nullptr;

    connect(tcp_server,&QTcpServer::newConnection,this,&Widget::new_connection_slot);
}

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

void Widget::on_start_button_clicked()
{
    // 监听( bind() + listen() )
    if(ui->start_button->text() == "启动"){
        QString ip = ui->ip_edit->text(); // 读取ip
        QString port = ui->port_edit->text(); // 读取port
        if(!tcp_server->listen(QHostAddress(ip),port.toUShort())){
            ui->plainTextEdit->setPlainText("服务端启动失败....");
        }
        else{
            ui->plainTextEdit->setPlainText("服务端启动成功....");
            ui->start_button->setText("断开"); // 改变按钮文本
        }
    }
    else if(ui->start_button->text() == "断开"){
        tcp_server->close(); // 关闭
        ui->plainTextEdit->appendPlainText("服务器断开成功....");
        ui->start_button->setText("启动"); // 改变按钮文本
    }
}

void Widget::new_connection_slot()
{
    tcp_socket = tcp_server->nextPendingConnection();
    QString client_ip = tcp_socket->peerAddress().toString(); // 获取客户端ip(转换成QString)
    quint16 client_port = tcp_socket->peerPort();
    ui->plainTextEdit->appendPlainText(QString("客户端 IP: %1  PORT:%2 连接成功").arg(client_ip).arg(client_port));
    connect(tcp_socket,&QTcpSocket::readyRead,this,&Widget::ready_read_slot);
}

void Widget::ready_read_slot()
{
    QByteArray buf = tcp_socket->readAll(); // 读数据
    QString s = QString::fromLocal8Bit(buf); // 编码转换
    ui->plainTextEdit->appendPlainText(QString("服务端发来数据:%1").arg(QString(s))); // 显示
}

void Widget::on_send_button_clicked()
{
    QString buf = ui->send_edit->text(); // 读数据
    tcp_socket->write(buf.toLocal8Bit()); // 发送数据
    ui->plainTextEdit->appendPlainText(QString("服务端发送数据:%1").arg(buf)); // 显示

}
widget.ui

输出:


客户端:

代码:

widget.h
cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_start_button_clicked(); // 连接按钮slot
    void ready_read_slot(); // 可读slot
    void on_send_button_clicked(); // 发送按钮slot

private:
    Ui::Widget *ui;
    QTcpSocket *tcp_sock; // socket
};

#endif // WIDGET_H
widget.cpp
cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    tcp_sock = new QTcpSocket(this);
    this->setWindowTitle("网络调试器客户端"); // 标题

    connect(tcp_sock,&QTcpSocket::readyRead,this,&Widget::ready_read_slot);
}

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

void Widget::on_start_button_clicked()
{
    QString ip = ui->ip_edit->text(); // 获取ip
    QString port = ui->port_edit->text(); // 获取port
    if(ui->start_button->text() == "连接"){
        tcp_sock->connectToHost(ip,port.toUShort()); // 连接
        if(tcp_sock->waitForConnected()){
            ui->plainTextEdit->setPlainText("连接服务器成功...");
            ui->start_button->setText("断开"); // 改变按钮文本
        }
        else{
            ui->plainTextEdit->setPlainText("连接服务器失败...");
        }
    }
    else if(ui->start_button->text() == "断开"){
        tcp_sock->close(); // 关闭
        ui->plainTextEdit->appendPlainText("客户端断开成功....");
        ui->start_button->setText("连接"); // 改变按钮文本
    }
}

void Widget::ready_read_slot(){
    QByteArray buf = tcp_sock->readAll(); // 读数据
    QString data = QString::fromLocal8Bit(buf); // 编码转换
    ui->plainTextEdit->appendPlainText(QString("服务端发来数据 %1").arg(data));
}

void Widget::on_send_button_clicked()
{
    QString buf = ui->send_edit->text(); // 获取数据
    tcp_sock->write(buf.toLocal8Bit()); // 编码转换
    ui->plainTextEdit->appendPlainText(QString("服务端发送数据 %1").arg(buf));
}
widget.ui

输出:


测试:

同时打开服务端和客户端

启动服务端并连接客户端

发送文本测试

断开连接

相关推荐
*小雪4 小时前
uniapp写H5授权登录及分享,返回到目标页面
开发语言·javascript·uni-app
ghie90905 小时前
C#语言中使用“using“关键字的介绍
开发语言·c#
七夜zippoe5 小时前
Java性能调优工具篇:JMH基准测试与Profiler(JProfiler/Async-Profiler)使用指南
java·开发语言·jprofiler·jmh·async-profiler
龙泉寺天下行走5 小时前
MinGW-w64 工具链(GCC 编译器) 的不同构建版本的区别
c++
代码AC不AC6 小时前
【C++】异常
c++·学习·异常
小龙报6 小时前
《嵌入式成长系列之51单片机 --- Keil5创建工程》
c语言·开发语言·c++·单片机·嵌入式硬件·51单片机·学习方法
柒儿吖6 小时前
Qt for HarmonyOS 3D图片轮播组件开源鸿蒙开发实战
qt·3d·harmonyos
9ilk6 小时前
【基于one-loop-per-thread的高并发服务器】--- 项目测试
运维·服务器·c++·后端·中间件
无限进步_6 小时前
【C语言】贪吃蛇游戏设计思路深度解析:从零开始理解每个模块
c语言·开发语言·c++·git·游戏·github·visual studio
听风吟丶6 小时前
Java 函数式编程深度实战:从 Lambda 到 Stream API 的工程化落地
开发语言·python