QT编写tcp通信工具(Client篇)

 更新时间:2022年08月19日 11:55:43   作者:林子xxx  
这篇文章主要介绍了QT编写tcp通信工具,适用于Client端,类似网上常见的网络调试工具,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了QT编写tcp通信工具的具体实现代码,Client篇,供大家参考,具体内容如下

1.说明

使用qt写一个类似网上常见的网络调试工具。此篇为Client端。下一遍再写Server端

2.基本流程

Client端相对简单:创建QTcpSocket对象,为对象的readyRead,error,connected(可选)分别写槽函数,以处理读数据,错误,连接成功三个事件。

连接使用对象的connectToHost方法,断开使用disconnectFromHost方法。

程序不做编码转换处理,因为之前的几遍文字已经做过,不再赘述。

3.代码

这是mainwindow.cpp文件。

#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->splitter->setStretchFactor(0,2);
    ui->splitter->setStretchFactor(1,1);
 
    QString ip=getLocalip();
    if( ip.isEmpty() )
    {
        QMessageBox::about(this,tr("提示"),tr("无本地IP。") ) ;
    }
    else{
        ui->ledtIpLocal->setText( ip );   //本地IP
    }
    ui->labHostName->setText(tr("HostName:")+ QHostInfo::localHostName() );
    ui->labHostName->adjustSize();
    ui->ledtPortServer->setText(tr("8080")); //默认
    ui->ledtIpServer->setText (ui->ledtIpLocal->text() );
    ui->btnOpen->setEnabled(true);
    ui->btnSend->setEnabled(false);
    //初始化TCP客户端
    tcpClient = new QTcpSocket(this);
    tcpClient->abort();
 
    connect(tcpClient, SIGNAL(readyRead()), this, SLOT(slot_readData()) );
    connect(tcpClient, SIGNAL(connected()), this, SLOT(slot_connected()) );
    connect(tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(slot_error(QAbstractSocket::SocketError)));
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
//获取本地IP
QString MainWindow::getLocalip()
{
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    foreach (QHostAddress address, list)
    {
        if(address.protocol() == QAbstractSocket::IPv4Protocol)
        {
            return address.toString();
        }
    }
    return "";
}
 
//读取数据
void MainWindow::slot_readData()
{
    QByteArray buffer = tcpClient->readAll();
    if(!buffer.isEmpty())
    {
        ui->tedtRecive->appendPlainText( buffer );
    }
}
//连接成功,也可以在方法waitForConnected后面处理。
void MainWindow::slot_connected()
{
    ui->btnOpen->setText("断开");
    ui->btnSend->setEnabled(true);
    ui->btnOpen->setEnabled(true);
    ui->ledtPortLocal->setText( QString::number(tcpClient->localPort()) );
}
//错误处理
void  MainWindow::slot_error(QAbstractSocket::SocketError)
{
    tcpClient->disconnectFromHost();
    ui->btnOpen->setText(tr("连接"));
    ui->btnOpen->setEnabled(true);
    QMessageBox::warning(this,
        tr("注意!"),
        tcpClient->errorString(),
        QMessageBox::Ok ,
        QMessageBox::Ok) ;
}
//连接与断开
void MainWindow::on_btnOpen_clicked()
{
    if(ui->btnOpen->text() == "断开")
    {
        tcpClient->disconnectFromHost();
        if (
                tcpClient->state() == QAbstractSocket::UnconnectedState \
                ||(  tcpClient->waitForDisconnected(1000))
           )
        {
            ui->btnOpen->setText("连接");
            ui->btnSend->setEnabled(false);
        }
    }else{
        if(  ui->ledtPortServer->text().toInt() ==0 ){
            QMessageBox::about(this,tr("提示"),tr("请输入端口号。") ) ;
            return;
        }
        tcpClient->connectToHost(ui->ledtIpServer->text(), ui->ledtPortServer->text().toInt(),QIODevice::ReadWrite,QAbstractSocket::IPv4Protocol);
        ui->btnOpen->setEnabled(false);
        if( !tcpClient->waitForConnected(4000) ) //只等待4秒
        {
            tcpClient->disconnectFromHost();
            ui->btnOpen->setText(tr("连接"));
            ui->btnOpen->setEnabled(true);
            QMessageBox::warning(this,
                tr("注意!"),
                tcpClient->errorString(),
                QMessageBox::Ok ,
                QMessageBox::Ok) ;
        }
    }
}
//发送
void MainWindow::on_btnSend_clicked()
{
    if(  ui->tedtSend->toPlainText().isEmpty() ){
        QMessageBox::about(this,
        tr("提示"),
        tr("请输入发送数据。")
       ) ;
       return;
    }
 
    tcpClient ->write( ui->tedtSend->toPlainText().toUtf8() );
}

4.附加修改

使用中发现qt文本框对回车键按“\n”处理,即使是从其他地方粘贴进来也会自动将“\r\n”转为“\n”,这有时非常不方便,比如测试wifi模块的AT命令,还有一些固定格式的网络请求。

先对界面进行修改,添加一些功能物件:

这里对发送数据进行处理:

//发送
void MainWindow::on_btnSend_clicked()
{
 
    if(  ui->tedtSend->toPlainText().isEmpty() ){
        QMessageBox::about(this,
        tr("提示"),
        tr("请输入发送数据。")
       ) ;
       return;
    }
    QString str = ui->tedtSend->toPlainText() ;
    if( ui->checkBox2->isChecked() )
    {
         str.replace(tr("\n"),tr("\r\n"));
         str.replace(tr("\n\n"),tr("\n"));
    }
    if( ui->checkBox1->isChecked() )str.append(tr("\r\n"));
    tcpClient ->write( str.toUtf8() );
}
//计算字节数
void MainWindow::on_btnCalc_clicked()
{
    QString str = ui->tedtSend->toPlainText() ;
    int len1= str.toUtf8().length();
    if( ui->checkBox2->isChecked() )
    {
         str.replace(tr("\n"),tr("\r\n"));
         str.replace(tr("\n\n"),tr("\n"));
    }
    if( ui->checkBox1->isChecked() )str.append(tr("\r\n"));
 
   int len2= str.toUtf8().length();
    QMessageBox::about(this,
    tr("字节:"),
    tr("处理前:")+QString::number (len1,10)+tr(",处理后:")+ QString::number (len2,10)
   ) ;
}

为了更加方便使用,添加记忆功能,保持上次的填写的内容:

//读取ini文件对应信息
void MainWindow:: readIni(QString key, QString&value)
{
    QString path = "save.ini";
    //创建文件
    QSettings *config = new QSettings(path, QSettings::IniFormat);
    //读取信息
    QVariant variant = config->value(QString("info/") + key);
    value = variant.value<QString>();
    delete config;
}
 
//写入ini文件对应信息
void MainWindow::writeIni(QString key, QString value)
{
    QString path = "save.ini";
    //创建文件
    QSettings *config = new QSettings(path, QSettings::IniFormat);
    QVariant variant;
    variant.setValue(value);
    //信息写入文件
    config->beginGroup("info");
    config->setValue(key, variant);
    config->endGroup();
    delete config;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 一起来看看C语言的预处理注意点

    一起来看看C语言的预处理注意点

    这篇文章主要为大家详细介绍了C语言的预处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C语言实现五子棋人人对战

    C语言实现五子棋人人对战

    这篇文章主要为大家详细介绍了C语言实现五子棋人人对战,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • C语言实现链队列

    C语言实现链队列

    这篇文章主要为大家详细介绍了C语言实现链队列,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • C语言数据结构实现银行模拟

    C语言数据结构实现银行模拟

    这篇文章主要介绍了C语言数据结构实现银行模拟的相关资料,通过此文希望大家能理解离散化的方法,希望能帮助到大家,需要的朋友可以参考下
    2017-08-08
  • 减小VC6编译生成的exe文件的大小的方法

    减小VC6编译生成的exe文件的大小的方法

    这篇文章主要介绍了减小VC6编译生成的exe文件的大小的方法,需要的朋友可以参考下
    2015-01-01
  • C语言中函数的声明、定义及使用的入门教程

    C语言中函数的声明、定义及使用的入门教程

    这篇文章主要介绍了C语言中函数的声明、定义及使用的入门教程,重点讲述了main函数的相关知识,需要的朋友可以参考下
    2015-12-12
  • C语言中的指针 初阶

    C语言中的指针 初阶

    这篇文章主要介绍的是关于初级阶段学习C语言中指针的一些内容,那就是指针是什么?简单的说,就是通过它能找到以它为地址的内存单元。下面文章我们就来详细介绍该内容,需要的朋友可以参考一下
    2021-10-10
  • Vue自定义指令最佳实践教程分享

    Vue自定义指令最佳实践教程分享

    Vue 3 显著增强了自定义指令的功能,使其封装更加灵活和易用,本文将分为基础和进阶两部分,介绍如何实现常用的自定义指令,并提供最佳的项目组织方式,需要的朋友可以参考下
    2024-12-12
  • 一文搞懂C++11万能引用和右值引用

    一文搞懂C++11万能引用和右值引用

    本文主要介绍了C++11万能引用和右值引用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 浅谈C语言中strcpy,strcmp,strlen,strcat函数原型

    浅谈C语言中strcpy,strcmp,strlen,strcat函数原型

    下面小编就为大家带来一篇浅谈C语言中strcpy,strcmp,strlen,strcat函数原型。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04

最新评论