QT實現(xiàn)TCP客戶端自動連接
更新時間:2024年12月30日 09:19:26 作者:千冊
這篇文章主要為大家詳細(xì)介紹了QT中一個TCP客戶端自動連接的測試模型,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
版本 1:沒有取消按鈕
測試效果

缺陷:
無法手動停止
測試代碼
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)的測試網(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:有取消按鈕
測試效果

點(diǎn)擊canel按鈕后,就不會自動重連了:

測試代碼
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)的測試網(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實現(xiàn)TCP客戶端自動連接的詳細(xì)內(nèi)容,更多關(guān)于QT TCP客戶端的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語言之實現(xiàn)棧的基礎(chǔ)創(chuàng)建
這篇文章主要介紹了C語言之實現(xiàn)棧的基礎(chǔ)創(chuàng)建,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
深入探討Linux靜態(tài)庫與動態(tài)庫的詳解(一看就懂)
本篇文章是對Linux靜態(tài)庫與動態(tài)庫進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C語言數(shù)組學(xué)習(xí)之特殊矩陣的壓縮存儲
矩陣在計算機(jī)圖形學(xué)、工程計算中都占有舉足輕重的地位,本文將討論如何將矩陣更有效地存儲在內(nèi)存中,并且能夠方便地提取矩陣中的元素。感興趣的同學(xué)可以了解一下2021-12-12
C++中cin.getline()和getline()函數(shù)的區(qū)別小結(jié)
這篇文章主要介紹了C++中cin.getline()和getline()函數(shù)區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03

