一、前言
在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();//清除信息///初始化telnetm_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(); // 连接成功后关闭socketreturn true;} else {qDebug() << "Connection failed:" << socket.errorString();socket.close(); // 连接失败后关闭socketreturn 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();//获取本地IPui->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 codesui->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