QT實(shí)現(xiàn)TCP客戶端自動(dòng)連接
版本 1:沒(méi)有取消按鈕
測(cè)試效果
缺陷:
無(wú)法手動(dòng)停止
測(cè)試代碼
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); //設(shè)置默認(rèn)的測(cè)試網(wǎng)絡(luò)參數(shù) 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)); } }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__<<__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:有取消按鈕
測(cè)試效果
點(diǎn)擊canel按鈕后,就不會(huì)自動(dòng)重連了:
測(cè)試代碼
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 MyPushButton:public QPushButton{ 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); //設(shè)置默認(rèn)的測(cè)試網(wǎng)絡(luò)參數(shù) 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,dialog](){ 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實(shí)現(xiàn)TCP客戶端自動(dòng)連接的詳細(xì)內(nèi)容,更多關(guān)于QT TCP客戶端的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語(yǔ)言之實(shí)現(xiàn)棧的基礎(chǔ)創(chuàng)建
這篇文章主要介紹了C語(yǔ)言之實(shí)現(xiàn)棧的基礎(chǔ)創(chuàng)建,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07深入探討Linux靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的詳解(一看就懂)
本篇文章是對(duì)Linux靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05c++中的單例類(lèi)模板的實(shí)現(xiàn)方法詳解
這篇文章主要介紹了c++中的單例類(lèi)模板的實(shí)現(xiàn)方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03C語(yǔ)言數(shù)組學(xué)習(xí)之特殊矩陣的壓縮存儲(chǔ)
矩陣在計(jì)算機(jī)圖形學(xué)、工程計(jì)算中都占有舉足輕重的地位,本文將討論如何將矩陣更有效地存儲(chǔ)在內(nèi)存中,并且能夠方便地提取矩陣中的元素。感興趣的同學(xué)可以了解一下2021-12-12C++中cin.getline()和getline()函數(shù)的區(qū)別小結(jié)
這篇文章主要介紹了C++中cin.getline()和getline()函數(shù)區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03