一、环境介绍
QT版本: 5.12.6
编译环境: win10 64位
目标系统: Android
完整工程源码下载地址(包含APK文件): https://download.csdn.net/download/xiaolong1126626497/19051988
想学习QT的Android环境搭建看这里(win10版本): https://blog.csdn.net/xiaolong1126626497/article/details/117254453
(ubuntu版本): https://blog.csdn.net/xiaolong1126626497/article/details/117256660
想学习QT入门到精通编程的看这里:https://blog.csdn.net/xiaolong1126626497/article/details/116485145
二、功能介绍
本软件支持TCP协议网络调试,可以创建TCP客户端与TCP服务器;适合电子工程师、嵌入式工程作为网络调试的工具。
服务器支持多连接,支持显示已经连接的客户端信息,支持循环发送,应用程序固定为横屏显示。
三、核心源码
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); setWindowIcon(QIcon(":/image/14g.png")); //设置图标 SetStyle(":/qss/blue.css"); //设置样式表 setWindowTitle("TCP网络调试助手"); comboBox_config(); timer = new QTimer(this); //创建定时器 connect(timer, SIGNAL(timeout()), this, SLOT(update())); //关联槽函数 /*控件名字设置*/ ui->checkBox_ShowTime->setText("接收时间显示"); ui->checkBox_TxBit->setText("自动发送附加位\\r\\n"); ui->checkBox_LoopTx->setText("循环发送数据"); ui->label_4->setText("设置循环间隔ms时间:"); ui->pushButton_connect->setText("连接"); ui->pushButton_SendData->setText("发送"); ui->About->setText("帮助"); ui->label->setText("1.协议类型"); ui->label_ip->setText("2.本地IP地址"); ui->label_prot->setText("3.本地端口"); ui->label_SendCnt->setText("TX"); ui->label_RxCnt->setText("RX"); ui->pushButton_clear->setText("复位"); ui->plainTextEdit_ShowData->setEnabled(false); //不可编辑 ui->pushButton_cleanShow->setText("清除显示"); } //设置指定样式 void Widget::SetStyle(const QString &qssFile) { QFile file(qssFile); if (file.open(QFile::ReadOnly)) { QString qss = QLatin1String(file.readAll()); qApp->setStyleSheet(qss); QString PaletteColor = qss.mid(20, 7); qApp->setPalette(QPalette(QColor(PaletteColor))); file.close(); } } //基本配置 void Widget::comboBox_config() { /*第一部分:网络设置*/ //1.1 配置协议 ui->comboBox_protocol->addItem("TCP Server"); ui->comboBox_protocol->addItem("TCP Client"); //1.2. 获取并配置本地IP地址 QList<QHostAddress> list = QNetworkInterface::allAddresses(); for(int i=0;i<list.count();i++) { QHostAddress addr=list.at(i); if(addr.protocol() == QAbstractSocket::IPv4Protocol) { ui->comboBox_ipaddress->addItem(addr.toString()); } } //1.3 设置可编辑性 ui->comboBox_ipaddress->setEditable(true); //1.4. 设置默认端口号 ui->lineEdit_prot->setText("8080"); /*第二部分:发送设置*/ //2.1设置循环发送时间 ui->lineEdi_LoopTime->setText("1000"); //2.2 设置默认发送的内容 ui->lineEdit_InputTxDtat->setText("www.wanbangee.com"); //接收数量置0 TxCount=0; RxCount=0; /*第三部分:选择客户端时用于显示本地端口和IP*/ ClientShowLocalProtLabel =new QLabel("本地端口:"); ClientShowLocalIptLabel =new QLabel("本地IP地址:"); ClientEditProt= new QLineEdit; ClientEditIP= new QLineEdit; ClientLayout = new QHBoxLayout; ClientLayout->addWidget(ClientShowLocalIptLabel); ClientLayout->addWidget(ClientEditIP); ClientLayout->addWidget(ClientShowLocalProtLabel); ClientLayout->addWidget(ClientEditProt); /*第四部分:选服务器时用于显示已经连接的客户端*/ SaverShowLocalProtLabel =new QLabel("已连接的客户端列表:"); ClientComboBoxList=new QComboBox; ClientComboBoxList->setMinimumWidth(180); ServerLayout = new QHBoxLayout; ServerLayout->addWidget(SaverShowLocalProtLabel); ServerLayout->addWidget(ClientComboBoxList); ServerLayout->addStretch(); } Widget::~Widget() { timer->stop(); //停止定时器 delete timer; delete ui; } //创建服务器或者连接到服务器 void Widget::on_pushButton_connect_clicked() { if(ui->pushButton_connect->text()=="连接") { switch(ui->comboBox_protocol->currentIndex()) { case 0: //服务器模式 NewServer(); break; case 1: //客户端模式 NewClinet(); break; } }else { switch(ui->comboBox_protocol->currentIndex()) { case 0: //服务器模式 ui->pushButton_connect->setText("连接"); for(int i=0;i<TcpFarClientList.count();i++) { TcpFarClientList.at(i)->close(); TcpFarClientList.removeAt(i); } LocalTcpServer->close();//关闭服务器 //取消客户端列表显示 ui->verticalLayout_9->removeItem(ServerLayout); ClientComboBoxList->close(); SaverShowLocalProtLabel->close(); //断开服务器之后设置控件可用性 //创建服务器之后设置控件可用 ui->comboBox_ipaddress->setEnabled(true); ui->comboBox_protocol->setEnabled(true); ui->lineEdit_prot->setEnabled(true); break; case 1: //客户端模式 LocalTcpClientSocket->close(); break; } } } //服务器模式:创建服务器 void Widget::NewServer() { /*1. 实例化服务器*/ LocalTcpServer= new QTcpServer; /*2. 设置监听的端口和IP地址*/ quint16 port=QString(ui->lineEdit_prot->text()).toInt(); if(ui->comboBox_ipaddress->currentText()=="QHostAddress::Any") { LocalTcpServer->listen(QHostAddress::Any,port); }else { QHostAddress addr(ui->comboBox_ipaddress->currentText()); LocalTcpServer->listen(addr,port); } /*3. 关联连接信号,检测是否有新的客户端连接*/ connect(LocalTcpServer,SIGNAL(newConnection()),this,SLOT(NewTcpConnection())); ui->pushButton_connect->setText("断开连接"); //添加布局,显示已经连接的客户端列表 ui->verticalLayout_9->insertLayout(1,ServerLayout); ClientComboBoxList->show(); SaverShowLocalProtLabel->show(); //创建服务器之后设置控件可用 ui->comboBox_ipaddress->setEnabled(false); ui->comboBox_protocol->setEnabled(false); ui->lineEdit_prot->setEnabled(false); } //客户端模式:创建客户端 void Widget::NewClinet() { /*1. 创建本地客户端TCP套接字*/ LocalTcpClientSocket = new QTcpSocket; /*2. 设置服务器IP地址*/ QString Ipaddr=ui->comboBox_ipaddress->currentText(); QHostAddress FarServerAddr(Ipaddr); /*3. 连接客户端的信号槽*/ connect(LocalTcpClientSocket,SIGNAL(connected()),this,SLOT(LocalTcpClientConnectedSlot())); connect(LocalTcpClientSocket,SIGNAL(disconnected()),this,SLOT(LocalTcpClientDisconnectedSlot())); connect(LocalTcpClientSocket,SIGNAL(readyRead()),this,SLOT(LocalTcpClientReadDtatSlot())); /*4. 尝试连接服务器主机*/ int prot=ui->lineEdit_prot->text().toInt(); LocalTcpClientSocket->connectToHost(FarServerAddr,prot); } //客户端模式:响应连接上服务器之后的操作 void Widget::LocalTcpClientConnectedSlot() { //显示本地端口和IP ClientEditProt->setText(QString::number(LocalTcpClientSocket->localPort())); ClientEditIP->setText(LocalTcpClientSocket->localAddress().toString()); ui->verticalLayout_9->insertLayout(1,ClientLayout); ClientEditProt->show(); ClientEditIP->show(); ClientShowLocalProtLabel->show(); ClientShowLocalIptLabel->show(); //当连接上服务器之后设置控件不可用 ui->comboBox_ipaddress->setEnabled(false); ui->comboBox_protocol->setEnabled(false); ui->lineEdit_prot->setEnabled(false); ui->pushButton_connect->setText("断开连接"); } //客户端模式:断开服务器 void Widget::LocalTcpClientDisconnectedSlot() { ui->verticalLayout_9->removeWidget(ClientEditProt); ui->verticalLayout_9->removeWidget(ClientEditIP); ui->verticalLayout_9->removeWidget(ClientShowLocalProtLabel); ui->verticalLayout_9->removeWidget(ClientShowLocalIptLabel); ui->verticalLayout_9->removeItem(ClientLayout); ClientEditProt->close(); ClientEditIP->close(); ClientShowLocalProtLabel->close(); ClientShowLocalIptLabel->close(); ui->pushButton_connect->setText("连接"); //当断开上服务器之后设置控件可用 ui->comboBox_ipaddress->setEnabled(true); ui->comboBox_protocol->setEnabled(true); ui->lineEdit_prot->setEnabled(true); } //客户端模式:读取服务器发过来的数据 void Widget::LocalTcpClientReadDtatSlot() { //移动滚动条到底部 QScrollBar *scrollbar = ui->plainTextEdit_ShowData->verticalScrollBar(); if(scrollbar) { scrollbar->setSliderPosition(scrollbar->maximum()); } /*判断显示的数据长度是否超出*/ QString text=ui->plainTextEdit_ShowData->toPlainText(); if(text.length()>1000) ui->plainTextEdit_ShowData->setPlainText(""); //清空显示 QByteArray array=LocalTcpClientSocket->readAll(); //记录接收的字节数并显示 TxCount+=QString(array).toLocal8Bit().length(); ui->lcdNumber_RxNumber->display(TxCount); text=""; //判断是否需要显示时间 if(ui->checkBox_ShowTime->isChecked()) { QDateTime time = QDateTime::currentDateTime(); //获取系统现在的时间 text+= time.toString("yyyy-MM-dd hh:mm:ss ddd"); //设置显示格式 text+=" :"; } text+=QString("").fromLocal8Bit(array); ui->plainTextEdit_ShowData->appendPlainText(text); } void Widget::on_comboBox_protocol_activated(int index) { switch(index) { case 0: //服务器模式 ui->label_ip->setText("2.本地IP地址"); ui->label_prot->setText("3.本地端口号"); ui->comboBox_ipaddress->clear(); ui->comboBox_ipaddress->addItem("QHostAddress::Any"); break; case 1: //客户端模式 ui->label_ip->setText("2.服务器IP地址"); ui->label_prot->setText("3.服务器端口号"); ui->comboBox_ipaddress->clear(); break; } QList<QHostAddress> list = QNetworkInterface::allAddresses(); for(int i=0;i<list.count();i++) { QHostAddress addr=list.at(i); if(addr.protocol() == QAbstractSocket::IPv4Protocol) { ui->comboBox_ipaddress->addItem(addr.toString()); } } } //发送数据 void Widget::on_pushButton_SendData_clicked() { QString text=ui->lineEdit_InputTxDtat->text(); if(text.isEmpty()) { QMessageBox::warning(this,"发送错误","发送的数据不能为空!",QMessageBox::Ok); return; } if(ui->checkBox_TxBit->isChecked()) //发送附加位 { text+="\r\n"; } QByteArray array=text.toLocal8Bit(); int count=0; switch(ui->comboBox_protocol->currentIndex()) { case 0: //服务器模式 if(TcpFarClientList.count()<=0) { timer->stop(); //停止定时器 ui->checkBox_LoopTx->setChecked(false); //取消循环按钮选择 QMessageBox::warning(this,"发送错误","没有连接的客户端!",QMessageBox::Ok); return; } for(int i=0;i<TcpFarClientList.count();i++) { //取出地址列表中的一个客户端地址 QTcpSocket *item = TcpFarClientList.at(i); count=item->write(array); } TxCount+=count; break; case 1: //客户端模式 if(LocalTcpClientSocket->state()==QAbstractSocket::ConnectedState) { TxCount+=LocalTcpClientSocket->write(array); } else { LocalTcpClientSocket->close(); timer->stop(); //停止定时器 ui->checkBox_LoopTx->setChecked(false); //取消循环按钮选择 QMessageBox::warning(this,"发送错误","未连接服务器!",QMessageBox::Ok); return; } break; } ui->lcdNumber_TxNumber->display(TxCount); } //清除计数 void Widget::on_pushButton_clear_clicked() { TxCount=0; RxCount=0; ui->lcdNumber_RxNumber->display(0); ui->lcdNumber_TxNumber->display(0); } //服务器模式:响应新连接的客户端 void Widget::NewTcpConnection() { /*创建本地服务器套接字*/ QTcpSocket *ServerSocket=LocalTcpServer->nextPendingConnection(); /*关联可读信号*/ connect(ServerSocket,SIGNAL(readyRead()),this,SLOT(ReadTcpClientData())); /*关联断开信号*/ connect(ServerSocket,SIGNAL(disconnected()),this,SLOT(TcpClientDisconnected())); TcpFarClientList.append(ServerSocket);//添加到列表 //显示已经连接的客户端 ClientComboBoxList->clear(); for(int i=0;i<TcpFarClientList.count();i++) { QString info=TcpFarClientList.at(i)->peerAddress().toString(); info+=":"; info+=QString::number(TcpFarClientList.at(i)->peerPort()); ClientComboBoxList->addItem(info); } } //服务器模式:响应断开的客户端 void Widget::TcpClientDisconnected() { for(int i=0;i<TcpFarClientList.count();i++) { //取出地址列表中的一个客户端地址 QTcpSocket *item = TcpFarClientList.at(i); //判断该客户端是否已经断开 if(item->socketDescriptor()==-1) { TcpFarClientList.removeAt(i); } } //显示已经连接的客户端 ClientComboBoxList->clear(); for(int i=0;i<TcpFarClientList.count();i++) { QString info=TcpFarClientList.at(i)->peerAddress().toString(); info+=":"; info+=QString::number(TcpFarClientList.at(i)->peerPort()); ClientComboBoxList->addItem(info); } } //服务器模式:读数据 void Widget::ReadTcpClientData() { /*移动滚动条到底部*/ QScrollBar *scrollbar = ui->plainTextEdit_ShowData->verticalScrollBar(); if(scrollbar) { scrollbar->setSliderPosition(scrollbar->maximum()); } for(int i=0;i<TcpFarClientList.count();i++) { if(!TcpFarClientList.at(i)->atEnd()) { QByteArray array=TcpFarClientList.at(i)->readAll();; //记录接收的字节数并显示 RxCount+=QString(array).toLocal8Bit().length(); ui->lcdNumber_RxNumber->display(RxCount); QString text; //判断是否需要显示时间 if(ui->checkBox_ShowTime->isChecked()) { QDateTime time = QDateTime::currentDateTime(); //获取系统现在的时间 text+= time.toString("【yyyy-MM-dd hh:mm:ss ddd"); //设置显示格式 text+="】:"; } text+=QString("").fromLocal8Bit(array); ui->plainTextEdit_ShowData->appendPlainText(text); } } } //关于 void Widget::on_About_clicked() { QMessageBox::information(this,tr("帮助提示"),"本软件用于TCP网络协议调试!\n" "暂不支持UDP协议调试!\n" "如果第一次打开软件字体显示不全\n" "需要关闭应用第二次打开即可自动适应\n" "软件作者:DS小龙哥\n" "BUG反馈:1126626497@qq.com"); } //是否开始循环发送数据 void Widget::on_checkBox_LoopTx_clicked() { if(ui->checkBox_LoopTx->isChecked()) //是否选择复选框 { int cnt=ui->lineEdi_LoopTime->text().toInt(); if(cnt<=0) { QMessageBox::warning(this,"错误提示","发送的时间不合法!",QMessageBox::Ok); ui->checkBox_LoopTx->setChecked(false); return; } timer->start(cnt); } else { timer->stop(); //停止定时器 } } //定时发送 void Widget::update(void) { on_pushButton_SendData_clicked(); } void Widget::on_pushButton_cleanShow_clicked() { ui->plainTextEdit_ShowData->setPlainText(""); //清除数据 }