QT实现TCP客户端自动连接

2024-12-30 15:50

本文主要是介绍QT实现TCP客户端自动连接,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...

版本 1:没有取消按钮

 测试效果

QT实现TCP客户端自动连接

缺陷:

无法手动停止

测试代码

CMakeLists.txt

cmake_minimum_required(VERSION 3.19)
project(AutoConnect LANGUAGES CXX)
 
find_package(Qt6 6.5 REQUIRED COMPONENTS Core Widgets Network)
 
qt_standard_project_setup()
 
qt_add_executable(AutoConnect
    WIN32 MACOSX_BUNDLE
    main.cpp
 
    widget.h
    widget.ui
)
 
target_link_libraries(AutoConnect
    PRIVATE
        Qt::Core
        Qt::Widgets
        Qt6::Network
)
 
include(GNUInstallDirs)
 
install(TARGETS AutoConnect
    BUNDLE  DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
 
qt_generate_deploy_app_script(
    TARGET AutoConnect
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})

main.cpp 

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

widget.h

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QTcpSocket>
#include <QProgressDialog>
#include <QPushButton>
#include <QLabel>
#include <QHBoxLayout>
#include <QvboxLayout>
#include <QTextBrowser>
#include <QMouseEvent>
#include <QLineEdit>
#include <QDebug>
#include <QMetaObject>
#include <QProgressBar>
#include <QTimer>
 
class MyTextBrowser:public QTextBrowser
{
public:
    MyTextBrowser(QWidget *parent = nullptr)
        :QTextBrowser(parent)
    {
 
    }
 
    // QWidget interface
protected:
    virtual void mouseDoubleClickEvent(QMouseEvent *event) override{
        if(event->button() == Qt::LeftButton){
            this->clear();
        }
    }
};
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = nullptr)
        : QWidget(parent)
    {
        QVBoxLayout *root = new QVBoxLayout(this);
        QHBoxLayout *iplayout = new QHBoxLayout;
        QPushButton *button_connect = new QPushButton("connect",this);
        button_connect->setObjectName("connect");
        QLabel *ip_label = new QLabel("ip",this);
        QLabel *port_label = new QLabel("port",this);
 
        iplayout->addwidget(ip_label);
        iplayout->addWidget(ip_LineEdit);
        iplayout->addWidget(port_label);
        iplayout->addWidget(port_LineEdit);
        iplayout->addWidget(button_connect);
        iplayout->addStretch();
 
        root->addLayout(iplayout);
        root->addWidget(console,1);
 
        //设置默认的测试网络参数
        ip_LineEdit->setText("127.0.0.1");
        port_LineEdit->setText("6600");
 
        client->setObjectName("client");
 
        QMetaObject::connectSlotsByName(this);
    }
    ~Widget()
    {
    }
public slots:
    void auto_connect(){
        if(client->state() == QAbstractSocket::ConnectedState){
            client->disconnectFromHost();
            client->waitForDisconnected();
        }
 
        //client->waitForConnected();
        std::shared_ptr<QProgressDialog> dialog(new QProgressDialog(this));
        dialog->setLabelText("");
        QProgressBar *bar = new QProgressBar(dialog.get());
        bar->setTextVisible(false);
        dialog->setBar(bar);
        dialog->setLabelText("connecting ... ");
        dialog->setRange(0,0);
        dialog->setCancelButton(nullptr);
        dialog->setWindowFlag(Qt::FramelessWindowHint);
        QMetaObject::Connection conn_accept
            = connect(client,
                      &QTcpSocket::connected,
                      dialog.get(),
                      &QProgressDialog::accept);
        QMetaObject::Connection conn_rejected
            = connect(client,
                      &QTcpSocket::stateChanged,
                      dialog.get(),[this,dialog](){
                          if(this->client->state() ==
                              QAbstractSocket::UnconnectedState){
                              dialog->reject();
                          }
                      });
        bool rtn = false;
        if(conn_accept&&conn_accept){
            QHostAddress ip(ip_LineEdit->text());
            int port = port_LineEdit->text().toInt();
            show_msg(QString("connect %1:%2 ...").arg(ip.toString()).arg(port));
            client->connectToHost(ip,port);
            rtn = dialog->exec();
            qDebug() << "rtn = " << rtn;
            if(rtn == true){
                show_msg(QString("connect %1:%2 success").arg(ip.toString()).arg(port));
            }else{
                show_msg(QString("connect %1:%2 fail").arg(ip.toString()).arg(port));
            }python
        }else{
            qDebug() << "error";
        }
 
        if(conn_accept){
            QObject::disconnect(conn_accept);
        }
        if(conn_rejected){
            QObject::disconnect(conn_rejected);
        }
        if(!rtn){
            QTimer::singleShot(10, this, &Widget::auto_connect);
        }
    }
    void on_connect_clicked(){
        qDebug() << "clicked";
        auto_connect();
    }
    void on_client_connected(){
        QTcpSocket *c = (QTcpSocket *)sender();
        qDebug() << c->peerAddress() << "-" << c->peerName() << "-" << c->peerPort();
 
        show_msg(QString("connect %1:%2 ok").arg(c->peerAddress().toString()).arg(c->peerPort()));
    }
    void on_client_disconnected(){
        qDebug() << __func__<<__LINE__;
        show_msg(QString("disconnected"));
        QTimer::singleShot(10, this, &Widget::auto_connect);
    }
    void on_client_errorOccurred(QAbstractSocket::SocketError socketError){
        qDebug() << __func__<<__LINE__ << "socketError:" << socketError;
    }
    void on_client_hostFound(){
        qDebug() << __func__<<__LINE__;
    }
    // void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
    void on_client_stateChanged(QAbstractSocket::SocketState socketState){
        qDebug() << __func__<<__LINE__<< "socketState:"<<socketState;
    }
    void show_msg(QString msg){
        console->append(msg);
    }
 
    void on_client_aboutToClose(){
        qDebug() << __func__<<__LINE__;
    }
    // void bytesWritten(qint64 bytes)
    // void channelBytesWritten(int channel, qint64 bytes)
    void on_client_channelReadyRead(int channel){
        qDebug() << __func__<<__LINE__<< "channel:"<<channel;
    }
    void on_client_readChannelFinished(){
        qDebug() << __func__<<__LINE__;
    }
    void on_client_readyRead(){
        qDebug() << __func__<www.chinasem.cn<__LINE__;
    }
 
public:
    QTcpSocket *client = new QTcpSocket(this);
    MyTextBrowser *console = new MyTextBrowser;
    QLineEdit *ip_LineEdit = new QLineEdit;
    QLineEdit *port_LineEdit = new QLineEdit;
 
private:
};
#endif // WIDGET_H

版本 2:有取消按钮

测试效果

QT实现TCP客户端自动连接

点击canel按钮后,就不会自动重连了:

QT实现TCP客户端自动连接

测试代码

CMakeLists.txt

cmake_minimum_required(VERSION 3.19)
project(AutoConnect LANGUAGES CXX)
 
find_package(Qt6 6.5 REQUIRED COMPONENTS Core Widgets Network)
 
qt_standard_project_setup()
 
qt_add_executable(AutoConnect
    WIN32 MACOSX_BUNDLE
    main.cpp
 
    widget.h
    widget.ui
)
 
target_link_libraries(AutoConnect
    PRIVATE
        Qt::Core
        Qt::Widgets
        Qt6::Network
)
 
include(GNUInstallDirs)
 
install(TARGETS AutoConnect
    BUNDLE  DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
 
qt_generate_deploy_app_script(
    TARGET AutoConnect
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})

main.cpp

#include "widget.h"
 
#include <QApplication>
int MyPushButton::count = 0;
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QApplication>
#include <QWidget>
#include <QTcpSocket>
#include <QProgressDialog>
#include <QPushButton>
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QTextBrowser>
#include <QMouseEvent>
#include <QLineEdit>
#include <QDebug>
#include <QMetaObject>
#include <QProgressBar>
#include <QTimer>
 
class MyTextBrowser:public QTextBrowser
{
public:
    MyTextBrowser(QWidget *parent = nullptr)
        :QTextBrowser(parent)
    {
 
    }
 
    // QWidget interface
protected:
    virtual void mouseDoubleClickEvent(QMouseEvent *event) override{
        if(event->button() == Qt::LeftButton){
            this->clear();
        }
    }
};
class www.chinasem.cnMyPushButton:public QPushButton{China编程
    Q_OBJECT
public:
 
    MyPushButton(QWidget *parent = nullptr):
        MyPushButton("",parent)
    {
 
    }
    MyPushButton(const QString &text, QWidget *parent = nullptr)
        :QPushButton(text,parent)
    {
        MyPushButton::count++;
        qDebug() << __func__ << __LINE__ << " create MyPushButton:count = "  << count;
 
    }
    ~MyPushButton(){
        MyPushButton::count--;
        qDebug() << __func__ << __LINE__ << " delete MyPushButton:count = " << count;
    }
public:
    static int count;
signals:
    void user_click();
 
 
    // QWidget interface
protected:
    virtual void mousePressEvent(QMouseEvent *event) override{
        if(event->button() == Qt::LeftButton){
            qDebug() << __func__ << __LINE__ << "user click";
            emit user_click();
        }
    }
};
 
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = nullptr)
        : QWidget(parent)
    {
        QVBoxLayout *root = new QVBoxLayout(this);
        QHBoxLayout *iplayout = new QHBoxLayout;
        QPushButton *button_connect = new QPushButton("connect",this);
 
        button_connect->setObjectName("connect");
        QLabel *ip_label = new QLabel("ip",this);
        QLabel *port_label = new QLabel("port",this);
 
        iplayout->addWidget(ip_label);
        iplayout->addWidget(ip_LineEdit);
        iplayout->addWidget(port_label);
        iplayout->addWidget(port_LineEdit);
        //iplayout->addWidget(button_connect);
        button_connect->setVisible(false);
        iplayout->addStretch();
 
        root->addLayout(iplayout);
        root->addWidget(console,1);
 
        //设置默认的测试网络参数
        ip_LineEdit->setText("127.0.0.1");
        port_LineEdit->setText("6600");
 
        client->setObjectName("client");
 
        QMetaObject::connectSlotsByName(this);
        QTimer::singleShot(10, this, &Widget::auto_connect);
 
        // std::shared_ptr<QProgressDialog> dialog(new QProgressDialog(this));
        // dialog->setCancelButton(new MyPushButton("hello",this));
        // qDebug() << "wait ...";
        // dialog.reset();
        // qDebug() << "byebye ...";
    }
    ~Widget()
    {
    }
public slots:
    void auto_connect(){
        if(client->state() == QAbstractSocket::ConnectedState){
            client->disconnectFromHost();
            client->waitForDisconnected();
        }
        //client->waitForConnected();
        std::shared_ptr<QProgressDialog> dialog(new QProgressDialog(this));
        dialog->setLabelText("");
        QProgressBar *bar = new QProgressBar(dialog.get());
        bar->setTextVisible(false);
        dialog->setBar(bar);
        dialog->setLabelText("connecting ... ");
        dialog->setRange(0,0);
        MyPushButton *cancel_button = new MyPushButton("cancel",dialog.get());
        dialog->setCancelButton(cancel_button);
        dialog->setWindowFlag(Qt::FramelessWindowHint);
        QMetaObject::Connection conn_accept
            = connect(client,
                      &QTcpSocket::connected,
                      dialog.get(),
                      &QProgressDialog::accept);
        QMetaObject::Connection conn_rejected
            = connect(client,
                      &QTcpSocket::stateChanged,
                      dialog.get(),[this,dialog](){
                          if(this->client->state() ==
                              QAbstractSocket::UnconnectedState){
                              qDebug() << "connect error";
                              dialog->reject();
                          }
                      });
 
        QMetaObject::Connection conn_cancel
            = connect(cancel_button,
                      &MyPushButton::user_click,
                      dialog.get(),[this,dialjsog](){
                          qDebug() << "connect error";
                          dialog->reject();
                          this->m_user_cancel = true;
                          show_msg("user cancel reconnect");
                      });
 
        bool rtn = false;
        if(conn_accept&&conn_accept&&conn_cancel){
            QHostAddress ip(ip_LineEdit->text());
            int port = port_LineEdit->text().toInt();
            show_msg(QString("connect %1:%2 ...").arg(ip.toString()).arg(port));
            client->connectToHost(ip,port);
            rtn = dialog->exec();
            qDebug() << "rtn = " << rtn;
            if(rtn == true){
                show_msg(QString("connect %1:%2 success").arg(ip.toString()).arg(port));
            }else{
                show_msg(QString("connect %1:%2 fail").arg(ip.toString()).arg(port));
            }
        }else{
            qDebug() << "error";
        }
 
        if(conn_accept){
            QObject::disconnect(conn_accept);
        }
        if(conn_rejected){
            QObject::disconnect(conn_rejected);
        }
        if(conn_rejected){
            QObject::disconnect(conn_rejected);
        }
        if(conn_cancel){
            QObject::disconnect(conn_cancel);
        }
 
        if(!rtn){
            if(this->m_user_cancel == false){
                QTimer::singleShot(10, this, &Widget::auto_connect);
            }
        }
    }
    void on_connect_clicked(){
        qDebug() << "clicked";
        auto_connect();
    }
    void on_client_connected(){
        QTcpSocket *c = (QTcpSocket *)sender();
        qDebug() << c->peerAddress() << "-" << c->peerName() << "-" << c->peerPort();
 
        show_msg(QString("connect %1:%2 ok").arg(c->peerAddress().toString()).arg(c->peerPort()));
    }
    void on_client_disconnected(){
        qDebug() << __func__<<__LINE__;
        show_msg(QString("disconnected"));
        QTimer::singleShot(10, this, &Widget::auto_connect);
    }
    void on_client_errorOccurred(QAbstractSocket::SocketError socketError){
        qDebug() << __func__<<__LINE__ << "socketError:" << socketError;
    }
    void on_client_hostFound(){
        qDebug() << __func__<<__LINE__;
    }
    // void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
    void on_client_stateChanged(QAbstractSocket::SocketState socketState){
        qDebug() << __func__<<__LINE__<< "socketState:"<<socketState;
    }
    void show_msg(QString msg){
        console->append(msg);
    }
 
    void on_client_aboutToClose(){
        qDebug() << __func__<<__LINE__;
    }
    // void bytesWritten(qint64 bytes)
    // void channelBytesWritten(int channel, qint64 bytes)
    void on_client_channelReadyRead(int channel){
        qDebug() << __func__<<__LINE__<< "channel:"<<channel;
    }
    void on_client_readChannelFinished(){
        qDebug() << __func__<<__LINE__;
    }
    void on_client_readyRead(){
        qDebug() << __func__<<__LINE__;
    }
 
public:
    bool m_user_cancel = false;
    QTcpSocket *client = new QTcpSocket(this);
    MyTextBrowser *console = new MyTextBrowser;
    QLineEdit *ip_LineEdit = new QLineEdit;
    QLineEdit *port_LineEdit = new QLineEdit;
 
private:
};
#endif // WIDGET_H

以上就是QT实现TCP客户端自动连接的详细内容,更多关于QT TCP客户端的资料请关注China编程(www.chinasem.cn)其它相关文章!

这篇关于QT实现TCP客户端自动连接的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1152849

相关文章

Python视频剪辑合并操作的实现示例

《Python视频剪辑合并操作的实现示例》很多人在创作视频时都需要进行剪辑,本文主要介绍了Python视频剪辑合并操作的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录介绍安装FFmpegWindowsMACOS安装MoviePy剪切视频合并视频转换视频结论介绍

spring6+JDK17实现SSM起步配置文件

《spring6+JDK17实现SSM起步配置文件》本文介绍了使用Spring6和JDK17配置SSM(Spring+SpringMVC+MyBatis)框架,文中通过示例代码介绍的非常详细,对大家的... 目录1.配置POM文件2.在resource目录下新建beans.XML文件,用于配置spirng3

Python项目打包部署到服务器的实现

《Python项目打包部署到服务器的实现》本文主要介绍了PyCharm和Ubuntu服务器部署Python项目,包括打包、上传、安装和设置自启动服务的步骤,具有一定的参考价值,感兴趣的可以了解一下... 目录一、准备工作二、项目打包三、部署到服务器四、设置服务自启动一、准备工作开发环境:本文以PyChar

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是

Java文件上传的多种实现方式

《Java文件上传的多种实现方式》文章主要介绍了文件上传接收接口的使用方法,包括获取文件信息、创建文件夹、保存文件到本地的两种方法,以及如何使用Postman进行接口调用... 目录Java文件上传的多方式1.文件上传接收文件接口2.接口主要内容部分3.postman接口调用总结Java文件上传的多方式1

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用

Windows自动化Python pyautogui RPA操作实现

《Windows自动化PythonpyautoguiRPA操作实现》本文详细介绍了使用Python的pyautogui库进行Windows自动化操作的实现方法,文中通过示例代码介绍的非常详细,对大... 目录依赖包睡眠:鼠标事件:杀死进程:获取所有窗口的名称:显示窗口:根据图片找元素:输入文字:打开应用:依

Xshell远程连接失败以及解决方案

《Xshell远程连接失败以及解决方案》本文介绍了在Windows11家庭版和CentOS系统中解决Xshell无法连接远程服务器问题的步骤,在Windows11家庭版中,需要通过设置添加SSH功能并... 目录一.问题描述二.原因分析及解决办法2.1添加ssh功能2.2 在Windows中开启ssh服务2

springboot 加载本地jar到maven的实现方法

《springboot加载本地jar到maven的实现方法》如何在SpringBoot项目中加载本地jar到Maven本地仓库,使用Maven的install-file目标来实现,本文结合实例代码给... 在Spring Boothttp://www.chinasem.cn项目中,如果你想要加载一个本地的ja

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加