qt之telnet连接目标设备在线调试功能

news2024/11/20 12:35:06

一、前言

在QT下使用telnet连接目标设备,进行在线命令调试,也可配合ftp或ssh使用。

telnet某些库在qt5下不可用,无法获取登录信息,只能获取到连接信息,这里我用自己的方式判断是否成功登录

二、环境

window

qt5.7

三、正文

网上有很多开源的qt+telnet使用方法,基本都是依赖于第三方库qttelnet.cpp,这个文件我就不发出了,网上有很多免费下载连接,下面放上实现功能的核心代码

#include "apponline.h"
#include "ui_apponline.h"
#include "login.h"

apponline::apponline(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::apponline)
{
    ui->setupUi(this);
    this->setWindowModality(Qt::ApplicationModal);//窗口置顶
    this->setWindowTitle("在线调试");
    clearControls();//清除信息


    ///初始化telnet
    m_telnet = new QtTelnet(this);
    connect(m_telnet, SIGNAL(message(const QString &)),this,SLOT(telnetMessage(const QString &)));
    connect(m_telnet, SIGNAL(loginRequired()),this, SLOT(telnetLoginRequired()));//qt6好使
    connect(m_telnet, SIGNAL(loginFailed()),this, SLOT(telnetLoginFailed()));//qt6好使
    connect(m_telnet, SIGNAL(loggedOut()),this, SLOT(telnetLoggedOut()));
    connect(m_telnet, SIGNAL(loggedIn()),this, SLOT(telnetLoggedIn()));//qt6好使
    connect(m_telnet, SIGNAL(connectionError(QAbstractSocket::SocketError)),this, SLOT(telnetconnectionError(QAbstractSocket::SocketError)));

}

apponline::~apponline()
{
    m_telnet->logout();
    m_telnet->close();
    m_telnet->destroyed();

    delete ui;
    qDebug()<<"apponline free";
}

//连接设备按键
void apponline::on_btnConn_2_clicked()
{
    //重新初始化
    m_telnet->logout();
    m_telnet->close();
    m_telnet->deleteLater();
    m_telnet = nullptr;
    m_telnet = new QtTelnet(this);
    connect(m_telnet, SIGNAL(message(const QString &)),this,SLOT(telnetMessage(const QString &)));
    connect(m_telnet, SIGNAL(loginRequired()),this, SLOT(telnetLoginRequired()));//qt6好使
    connect(m_telnet, SIGNAL(loginFailed()),this, SLOT(telnetLoginFailed()));//qt6好使
    connect(m_telnet, SIGNAL(loggedOut()),this, SLOT(telnetLoggedOut()));
    connect(m_telnet, SIGNAL(loggedIn()),this, SLOT(telnetLoggedIn()));//qt6好使
    connect(m_telnet, SIGNAL(connectionError(QAbstractSocket::SocketError)),this, SLOT(telnetconnectionError(QAbstractSocket::SocketError)));
    on_btnclear1_clicked();
    on_btnclear2_clicked();
    clearControls();//清除信息
    if (isTelnetConnected(sIP,23)) {
        // 连接成功的处理
        m_Telnetconnectflag=1;//Telnet连接登录状态  0:未登录 1:连接成功 2:登录成功
        ui->textEdit->append("连接目标设备成功,点击【登录账户】按键登录,成功后可进行在线调试");
        //telnet连接
        m_telnet->connectToHost(sIP);
        ui->btnConn_2->setEnabled(false);
    } else {
        // 连接失败的处理
        m_Telnetconnectflag=0;//Telnet连接登录状态  0:未登录 1:连接成功 2:登录成功
        ui->textEdit->append("未连接目标设备,请检查网络是否正常连接,请检查目标设备Telnet端口是否开启");
    }
}
//断开连接按键
void apponline::on_btnDisConn_2_clicked()
{
    m_telnet->logout();
    m_telnet->close();
    clearControls();//清除信息
}
//判断设备网络连接
bool apponline::isTelnetConnected(const QString &host, quint16 port)
{
    QTcpSocket socket;
    socket.connectToHost(host, port);
    if (socket.waitForConnected(3000)) { // 等待3秒来建立连接
        qDebug() << "Connected to" << host << "on port" << port;
        socket.close(); // 连接成功后关闭socket
        return true;
    } else {
        qDebug() << "Connection failed:" << socket.errorString();
        socket.close(); // 连接失败后关闭socket
        return false;
    }
}
//清空
void apponline::on_btnclear1_clicked()
{
    ui->textEdit->clear();
}
void apponline::on_btnclear2_clicked()
{
    ui->textEdit_2->clear();
}
//清除信息
void apponline::clearControls()
{
    m_Telnetconnectflag=0;//Telnet连接登录状态  0:未登录 1:连接成功 2:登录成功
    ui->textEdit->clear();
    ui->textEdit->append("本机IP地址:");
    getLocalIPs();//获取本地IP
    ui->btnConn_2->setEnabled(true);
}
//登录账户按键
void apponline::on_pushButton_clicked()
{
    //判断账号密码输入栏是否为空,进行错误提示
    if(ui->lineEdit_name->text().isEmpty()||ui->lineEdit_passwd->text().isEmpty()){
        massage_dialog(1,"提示","设备账户或密码不能为空!",1,30);
        return;
    }
    //判断是否连接成功
    if(m_Telnetconnectflag==0){//Telnet连接登录状态  0:未登录 1:连接成功 2:登录成功
        massage_dialog(1,"提示","请先连接目标设备!",1,30);
        return;
    }
    if(m_Telnetconnectflag==2){//Telnet连接登录状态  0:未登录 1:连接成功 2:登录成功
        massage_dialog(1,"提示","已登陆账户!",1,30);
        return;
    }
    ui->pushButton->setEnabled(false);
    QTimer::singleShot(100,this,[=]{m_telnet->sendData(ui->lineEdit_name->text());});
    QTimer::singleShot(500,this,[=]{m_telnet->sendData(ui->lineEdit_passwd->text());});
    QTimer::singleShot(3000,this,[=]{ui->pushButton->setEnabled(true);});
}

//回车发送telnet命令
void apponline::on_Qtelnet_lineEdit_returnPressed()
{
    //判断是否连接成功
    if(m_Telnetconnectflag==0){//Telnet连接登录状态  0:未登录 1:连接成功 2:登录成功
        massage_dialog(1,"提示","请先连接目标设备!",1,30);
        return;
    }
    QString cmd = ui->Qtelnet_lineEdit->text();
    m_telnet->sendData(cmd);
    writeLog(QString("在线调试telnet发送:").arg(cmd));//日志记录
}
//combox选择发送telnet命令
void apponline::on_comboBox_activated(const QString &arg1)
{
    //判断是否连接成功
    if(m_Telnetconnectflag!=2){//Telnet连接登录状态  0:未登录 1:连接成功 2:登录成功
        massage_dialog(1,"提示","请先连接目标设备!",1,30);
        return;
    }
    m_telnet->sendData(arg1);
    writeLog(QString("在线调试telnet发送:").arg(arg1));//日志记录
}



///QtTelnet

//接收telnet消息
void apponline::telnetMessage(const QString &msg)
{
    QString nmsg(msg);
    nmsg.remove("\r");
//    nmsg.remove("root");
//    nmsg.remove("SYSYKJsysykj123..");
//    nmsg.remove("A40i login:");
//    nmsg.remove("Password:");
    nmsg.remove(QRegExp("\033\\[[0-9;]*[A-Za-z]")); // Also remove terminal control codes
    ui->textEdit_2->append(nmsg);
    //判断登录成功,使用符号 # 判断,登录成功后会出现此符号
    if(nmsg.contains('#')){
        if(m_Telnetconnectflag==1)//判断第一次登录
            ui->textEdit->append("登录目标设备成功,可进行在线调试");
        m_Telnetconnectflag=2;//Telnet连接登录状态  0:未登录 1:连接成功 2:登录成功

    }

}
//登录  此函数QT6使用,QT5不触发
void apponline::telnetLoginRequired()
{
    qDebug()<<"telnetLoginRequired";
//    QString user = ui->lineEdit_name->text();
//    QString passwd  = ui->lineEdit_passwd->text();
//    if(user == "" || passwd == ""){
//        ui->textEdit->append("用户名和密码不能为空!");
//        return;
//    }
//    m_telnet->login(user,passwd); // 登入telnet
}
//登录失败  此函数QT6使用,QT5不触发
void apponline::telnetLoginFailed()
{
    qDebug()<<"telnetLoginFailed";
    ui->textEdit->append("Telnet登录失败,请检查账号或密码是否正确");
}
//断开连接
void apponline::telnetLoggedOut()
{
    m_Telnetconnectflag=0;//Telnet连接登录状态  0:未登录 1:连接成功 2:登录成功
    ui->btnConn_2->setEnabled(true);
    qDebug()<<"telnetLoggedOut";
    ui->textEdit->append("Telnet在线调试断开连接");
}
//登录成功  此函数QT6使用,QT5不触发
void apponline::telnetLoggedIn()
{
    qDebug()<<"telnetLoggedIn";
    ui->textEdit->append("Telnet登录成功,可以执行在线调试功能");
}
//错误信息
void apponline::telnetconnectionError(QAbstractSocket::SocketError error)
{
    qDebug()<<"err:"<<error;
}


// 获取本机所有 IP 地址
void apponline::getLocalIPs() {
    QList<QHostAddress> ipAddressesList;
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    foreach (QNetworkInterface item, interfaces) {
        if (item.flags() & QNetworkInterface::IsUp && !(item.flags() & QNetworkInterface::IsLoopBack)) {
            QList<QNetworkAddressEntry> addressEntries = item.addressEntries();
            foreach (QNetworkAddressEntry entry, addressEntries) {
                if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol)
                    ipAddressesList.append(entry.ip());
            }
        }
    }
    // 输出所有 IP 地址
    foreach (QHostAddress address, ipAddressesList) {
        //        qDebug() << address.toString();
        ui->textEdit->append(address.toString());
    }
}

可以看见telnet的原生信号中登录命令是备注qt5不好使的,疑是qt6可用,但是我的电脑环境没有qt6,暂时也用不上,暂时没有测试,有环境的童鞋可以自己测试一下。

既然登录状态函数不好使,那么就得通过其他方式去判断用户的账号密码是否登录成功,这里我就是简单的通过接收命令中是否有#符号出现,这个符号一般就是登录成功后出现的第一个字符。

界面UI如下所示

有些控件按键没有用,大家可以自行根据核心代码进行修改。

四、结语

telnet

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2244032.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android中常见内存泄漏的场景和解决方案

本文讲解Android 开发中常见内存泄漏场景及其解决方案&#xff0c;内容包括代码示例、原因分析以及最佳实践建议。 1. 静态变量导致的内存泄漏 静态变量的生命周期与应用进程一致&#xff0c;如果静态变量持有了对 Activity 或其他大对象的引用&#xff0c;就可能导致内存泄漏…

红外相机和RGB相机外参标定 - 无需标定板方案

1. 动机 在之前的文章中红外相机和RGB相机标定&#xff1a;实现两种模态数据融合_红外相机标定-CSDN博客 &#xff0c;介绍了如何利用标定板实现外参标定&#xff1b;但实测下来发现2个问题&#xff1a; &#xff08;1&#xff09;红外标定板尺寸问题&#xff0c;由于标定板小…

即插即用篇 | YOLOv11 引入高效的直方图Transformer模块 | 突破天气障碍:Histoformer引领高效图像修复新路径

本改进已同步到YOLO-Magic框架&#xff01; 摘要&#xff1a;摘要。基于Transformer的恶劣天气图像修复方法取得了显著进展。大多数方法通过沿通道维度或在空间上固定范围的块内使用自注意力&#xff0c;以减少计算负担。然而&#xff0c;这种折中方式在捕获长距离空间特征方面…

ITSS服务经理: 山西科技学院智能铸造现代产业学院揭牌

记者从山西科技学院传来喜讯&#xff0c;近日&#xff0c;在该院工程训练中心与智能铸造现代产业学院于山西省晋城市泽州县绿色智能铸造创新产业园隆重举行的揭牌启动仪式上&#xff0c;标志着学院迈入崭新篇章。应用型本科高校&#xff0c;作为孕育高素质应用人才的摇篮&#…

AI时代:弯道超车的新思维与实践路径

文章目录 一、AI时代的机遇与挑战二、重新认识AI三、弯道超车的新思维四、实践路径与案例分享五、AI技术的未来发展趋势六、个人与企业如何适应AI时代《AI时代&#xff1a;弯道超车新思维》内容简介作者简介目录 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#…

‘视’不可挡:OAK相机助力无人机智控飞行!

南京邮电大学通达学院的刘同学用我们的oak-d-lite实现精确打击无人机的避障和目标识别定位功能&#xff0c;取得了比赛冠军。我们盼望着更多的朋友们能够加入到我们OAK的队伍中来&#xff0c;参与到各式各样的比赛中去。我们相信&#xff0c;有了我们相机的助力&#xff0c;大家…

网页抓取API,让数据获取更简单

网页抓取的过程通常分为以下步骤&#xff0c;尤其是在面对静态网页时&#xff1a; 获取页面 HTML&#xff1a;使用 HTTP 客户端下载目标页面的 HTML 内容。解析 HTML&#xff1a;将下载的 HTML 输入解析器&#xff0c;准备提取内容。提取数据&#xff1a;利用解析器功能&#…

Java学习笔记--数组常见算法:数组翻转,冒泡排序,二分查找

一&#xff0c;数组翻转 1.概述:数组对称索引位置上的元素互换&#xff0c;最大值数组序号是数组长度减一 创建跳板temp&#xff0c;进行min和max的互换&#xff0c;然后min自增&#xff0c;max自减&#xff0c;当min>max的时候停止互换&#xff0c;代表到中间值 用代码实…

Office-Tab-for-Mac Office 窗口标签化,Office 多文件标签化管理

Office Tab&#xff1a;让操作更高效&#xff0c;给微软 Office 添加多标签页功能 Office 可以说是大家装机必备的软件&#xff0c;无论学习还是工作都少不了。其中最强大、用的最多的&#xff0c;还是微软的 Microsoft Office。 遗憾的是&#xff0c;微软的 Office 不支持多…

游戏引擎学习第12天

视频参考:https://www.bilibili.com/video/BV1yom9YnEWY 这节没讲什么东西&#xff0c;主要是改了一下音频的代码 后面有介绍一些alloc 和malloc,VirtualAlloc 的东西 _alloca 函数&#xff08;或 alloca&#xff09;分配的是栈内存&#xff0c;它的特点是&#xff1a; 生命周…

delphi fmx android 离线人脸识别

搜遍全网都没有找到delphi android 能用的 离线人脸识别,无需注册什么开发者 有这方面需求的可以用fsdk 这边用的luxand.FSDK8.0 android下的注册号要自己找下 1,用老猫的工具将android 下的sdk,FSDK.java 编译成FSDK.jar 老猫的工具 2,用上面的工具将FSDK.jar 生成de…

Java基础夯实——2.4 线程的生命周期

Java线程生命周期 Java线程的生命周期分为&#xff1a;新建&#xff08;New&#xff09;、就绪&#xff08;Runnable&#xff09;、阻塞&#xff08;Blocked&#xff09;、等待 (Waiting) 、计时等待&#xff08;Timed_Waiting&#xff09;、终止&#xff08;Terminated&#…

实现简易计算器 网格布局 QT环境 纯代码C++实现

问题&#xff1a;通过代码完成一个10以内加减法计算器。不需要自适应&#xff0c;界面固定360*350。 ""按钮90*140&#xff0c;其它按钮90*70。 参考样式 #define DEFULT_BUTTON_STYLE "\ QPushButton{\color:#000000;\border:1px solid #AAAAAA;\border-radi…

RNN公式解释:实现记忆功能;RNN的状态向量

目录 RNN公式解释:实现记忆功能 一、词向量 二、RNN的状态向量 三、词向量变为状态向量的过程 四、总结 RNN公式解释:实现记忆功能 在RNN(递归神经网络)中,词向量变为状态向量的过程,实际上是RNN处理时序数据的一个核心环节。以下是对这一过程的详细解释: 一、词向…

【Linux】基础02

Linux编译和调试 VI编辑文件 vi : 进入文件编辑 是命令行模式 i &#xff1a;从光标处进入插入模式 dd : 删除光标所在行 n dd 删除指定行数 Esc &#xff1a; 退出插入模式 &#xff1a; 冒号进入末行模式 :wq : 保存退出 :q &#xff1a; 未修改文件可以退出 :q! …

21.UE5游戏存档,读档,函数库

2-23 游戏存档、读档、函数库_哔哩哔哩_bilibili 目录 1.存档蓝图 2.函数库 2.1保存存档 2.2读取存档&#xff1a; 3.加载游戏&#xff0c;保存游戏 3.1游戏实例对象 3.2 加载游戏 3.3保存游戏 这一节的内容较为错综复杂&#xff0c;中间没有运行程序进行阶段性成果的验…

未来已来:少儿编程竞赛聚焦物联网,激发创新潜力

随着人工智能与物联网技术&#xff08;IoT&#xff09;的快速发展&#xff0c;少儿编程教育正在迎来新的变革浪潮。近年来&#xff0c;各类少儿编程竞赛纷纷增加了物联网相关主题&#xff0c;要求学生结合编程知识和硬件设备设计智能家居、智慧城市等创新项目。这一趋势不仅丰富…

布局设计器

介绍 最近遇到一个设计器的需求&#xff0c;要求拖拽布局&#xff0c;图层管理&#xff0c;自定义组件预览&#xff0c;分辨率等等功能。说白了就是先用设计器布局然后在屏幕上播放你布局好的内容 所以不多说了直接上代码 代码地址 这里大概说下有哪些功能吧 图层与属性框的值关…

Java中日志采集框架-JUL、Slf4j、Log4j、Logstash

1. 日志采集 日志采集是指在软件系统、网络设备、服务器或其他IT基础设施中自动收集日志文件和事件信息的过程。这些日志通常包含了时间戳、事件类型、源和目标信息、错误代码、用户操作记录等关键数据。日志采集的目的是为了监控系统运行状态、分析系统性能、审计用户行为、故…

ansible从入门到精通(完整篇)

ansible从入门到精通&#xff08;完整篇&#xff09; 转自ansible从入门到精通&#xff08;完整篇&#xff09; 文章目录 01 Ansible介绍与安装 1. 介绍 Ansible 1.1 什么是 Ansible?1.2 Ansible 无需代理1.3 Ansible 方式 2. 安装 Ansible 2.1 控制节点2.2 受管主机2.3…