qt学习:网络调试助手客户端+服务端
目录
客户端
步骤
ui界面配置编辑
添加头函数,类成员数据,类成员函数
添加模块
构造函数
连接按钮
收到来自服务器的数据触发
发送按钮
断开按钮
向textEditRev文本编辑器中插入指定颜色的文本
服务端
步骤
ui界面配置
添加头函数,类成员数据,类成员函数
添加模块
自定义一个继承与复选框类的类,重写鼠标点击事件,定义自定义信号
构造函数
新的TCP连接请求时触发
新的数据接收时触发
当连接的状态断掉时触发
当 QTcpSocket 的连接状态发生变化时,stateChanged信号会被发出 参数 socketState当前的套接字状态
当点击通信协议和服务器ip地址的复选框值会发送信号触发mComboBox_refresh函数
监听按钮
发送按钮
停止监听按钮
断开按钮
客户端
步骤
ui界面配置
添加头函数,类成员数据,类成员函数
#include <QTcpSocket>
#include <QWidget>private slots://连接按钮void on_btnConnect_clicked();//收到来自服务器的数据触发void mRead_Data_From_Server();//发送按钮void on_btnSend_clicked();//断开按钮void on_btndiscon_clicked();private:QTcpSocket *client;//tcp描述符//向textEditRev文本编辑器中插入指定颜色的文本void mInserTextByColor(Qt::GlobalColor color,QString str);
添加模块
QT += core gui network
构造函数
//断开按钮和发送按钮关闭ui->btndiscon->setEnabled(false);ui->btnSend->setEnabled(false);//创建新的QTcpSocket对象client = new QTcpSocket(this);//当client对象的数据可读(收到来自服务器的数据)时,readyRead()信号会被发出,//然后mRead_Data_From_Server()槽函数会被调用以处理接收到的数据connect(client,SIGNAL(readyRead()),this,SLOT(mRead_Data_From_Server()));
连接按钮
//连接按钮
void Widget::on_btnConnect_clicked()
{// 尝试连接到指定的IP地址和端口client->connectToHost(ui->lineEditIPAddr->text(),ui->lineEditPort->text().toInt());// 检查连接状态if(client->state() == QAbstractSocket::ConnectedState ||client->state()==QAbstractSocket::ConnectingState){// 如果连接成功或正在连接中,执行以下操作ui->textEditRev->append("连接成功!"); // 在文本编辑器中添加“连接成功!”的消息 ui->btnConnect->setEnabled(false); // 禁用“连接”按钮,因为它已经完成了连接操作 ui->lineEditPort->setEnabled(false); // 禁用端口输入框,因为连接已经建立 ui->lineEditIPAddr->setEnabled(false); // 禁用IP地址输入框,因为连接已经建立 ui->btndiscon->setEnabled(true); // 启用“断开”按钮,因为现在可以断开连接了 ui->btnSend->setEnabled(true); // 启用“发送”按钮,因为现在可以发送数据了 }
}
收到来自服务器的数据触发
//收到来自服务器的数据触发
void Widget::mRead_Data_From_Server()
{// 将文本编辑器的光标移动到末尾ui->textEditRev->moveCursor(QTextCursor::End);// 确保光标是可见的ui->textEditRev->ensureCursorVisible();// 调用mInserTextByColor函数,将接收到的数据以黑色插入到文本编辑器中 mInserTextByColor(Qt::black,client->readAll());
}
发送按钮
//发送按钮
void Widget::on_btnSend_clicked()
{// 获取文本编辑器textEditSend中的纯文本内容,并将其转换为UTF-8编码的字节数组QByteArray sendData = ui->textEditSend->toPlainText().toUtf8();// 将sendData写入到client对象中,用于发送数据到服务器client->write(sendData);// 调用mInserTextByColor函数,将刚刚发送的数据以红色插入到textEditRev文本编辑器中mInserTextByColor(Qt::red,sendData);
}
断开按钮
//断开按钮
void Widget::on_btndiscon_clicked()
{// 断开与服务器的连接client->disconnectFromHost();// 关闭与服务器的连接client->close();// 在文本编辑器textEditRev中追加文本“断开连接!ui->textEditRev->append("断开连接!");// 启用连接按钮,允许用户重新建立连接 ui->btnConnect->setEnabled(true);// 启用端口输入框,允许用户输入端口号 ui->lineEditPort->setEnabled(true);// 启用IP地址输入框,允许用户输入IP地址 ui->lineEditIPAddr->setEnabled(true);// 禁用断开连接按钮,因为它已经处于断开状态 ui->btndiscon->setEnabled(false);// 禁用发送按钮,因为当前没有与服务器的连接 ui->btnSend->setEnabled(false);
}
向textEditRev文本编辑器中插入指定颜色的文本
//向textEditRev文本编辑器中插入指定颜色的文本
void Widget::mInserTextByColor(Qt::GlobalColor color,QString str)
{// 获取文本编辑器的当前文本光标QTextCursor cursor = ui->textEditRev->textCursor();// 创建一个文本字符格式对象QTextCharFormat format;// 设置字符格式的前景色为指定的颜色format.setForeground(QBrush(QColor(color)));// 应用字符格式到文本光标cursor.setCharFormat(format);// 在光标位置插入指定的字符串 cursor.insertText(str);
}
服务端
步骤
ui界面配置

添加头函数,类成员数据,类成员函数
#include <QMessageBox>
#include <QNetworkInterface>
#include <QTcpSocket>
#include <QTextCodec>
#include <QWidget>
#include <QTcpServer>
#include "mycombobox.h"public:QTcpServer* server;//tcp描述符public slots:void on_newClient_connect();//新的TCP连接请求时触发void on_readyRead_handler();//新的数据接收时触发void mdisconnected();//当连接的状态断掉时触发//当 QTcpSocket 的连接状态发生变化时,stateChanged信号会被发出 参数 socketState当前的套接字状态void mstateChanged(QAbstractSocket::SocketState socketState);//当点击通信协议和服务器ip地址的复选框值会发送信号触发mComboBox_refresh函数void mComboBox_refresh();
添加模块
QT += core gui network
自定义一个继承与复选框类的类,重写鼠标点击事件,定义自定义信号
#ifndef MYCOMBOBOX_H
#define MYCOMBOBOX_H
#include <QComboBox>
#include <QWidget>class MyComboBox : public QComboBox
{Q_OBJECT
public:MyComboBox(QWidget *parent);
protected:void mousePressEvent(QMouseEvent *e) override;
signals:void on_ComboBox_clicked();
};#endif // MYCOMBOBOX_H
#include "mycombobox.h"
#include <QMouseEvent>
MyComboBox::MyComboBox(QWidget *parent) : QComboBox(parent)
{}
void MyComboBox::mousePressEvent(QMouseEvent *e)
{if(e->button() == Qt::LeftButton){emit on_ComboBox_clicked();}QComboBox::mousePressEvent(e);
}
构造函数
//创建了一个新的QTcpServer对象server = new QTcpServer(this);//当点击通信协议和服务器ip地址的复选框值会发送信号触发mComboBox_refresh函数connect(ui->comboBoxChildren,&MyComboBox::on_ComboBox_clicked,this,&Widget::mComboBox_refresh);//当server对象的newConnection信号被触发时(新的TCP连接请求)on_newClient_connect槽函数会被调用connect(server,SIGNAL(newConnection()),this,SLOT(on_newClient_connect()));//禁用了三个按钮ui->btnLineout->setEnabled(false);ui->btnStopListen->setEnabled(false);ui->btnSend->setEnabled(false);//获取了所有网络接口的地址,并将它们存储在一个QList<QHostAddress>类型的变量addresss中QList<QHostAddress> addresss = QNetworkInterface::allAddresses();//遍历了addresss中的所有地址for(QHostAddress tmp : addresss){//检查该地址是否是一个IPv4地址if(tmp.protocol() == QAbstractSocket::IPv4Protocol){//将该地址的字符串表示添加到comboBoxAddr组合框中ui->comboBoxAddr->addItem(tmp.toString());}}
新的TCP连接请求时触发
//新的TCP连接请求时触发
void Widget::on_newClient_connect()
{// 检查是否有待处理的连接if(server->hasPendingConnections()){// 获取下一个待处理的连接QTcpSocket *connction = server->nextPendingConnection();// 输出客户端的地址和端口到调试信息qDebug() << "client Addr: " << connction->peerAddress().toString() << "port:" << connction->peerPort();// 在文本编辑器中插入客户端的地址和端口信息ui->textEditRev->insertPlainText("客户端地址:"+connction->peerAddress().toString()+"客户端端口号:"+QString::number(connction->peerPort()) +"\n");//::xxx:192.168.1.9// 当连接准备好读取数据时,调用on_readyRead_handler槽函数connect(connction,SIGNAL(readyRead()),this,SLOT(on_readyRead_handler()));// 当连接的状态改变时,调用mstateChanged槽函数并传递新的状态connect(connction,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(mstateChanged(QAbstractSocket::SocketState)));// 将客户端的端口号添加到组合框中,并设置为当前选中的文本ui->comboBoxChildren->addItem(QString::number(connction->peerPort()));ui->comboBoxChildren->setCurrentText(QString::number(connction->peerPort()));// 如果发送按钮当前是禁用的,则启用它if(!ui->btnSend->isEnabled()){ui->btnSend->setEnabled(true);}}
}
新的数据接收时触发
//新的数据接收时触发
void Widget::on_readyRead_handler()
{// sender() 函数返回发出当前信号的对象的指针// 使用 qobject_cast 将发送者转换为 QTcpSocket 指针QTcpSocket *tmpSock = qobject_cast<QTcpSocket *>(sender());// 读取所有可用的数据QByteArray revData = tmpSock->readAll();// 将文本编辑器的光标移动到末尾ui->textEditRev->moveCursor(QTextCursor::End);// 确保光标是可见的ui->textEditRev->ensureCursorVisible();// 在文本编辑器中插入新接收到的数据,前面带有 "客户端: " 的标签ui->textEditRev->insertPlainText("客户端: " + revData);
}
当连接的状态断掉时触发
//当连接的状态断掉时触发
void Widget::mdisconnected()
{// 使用 qobject_cast 将发送者转换为 QTcpSocket 指针QTcpSocket *tmpSock = qobject_cast<QTcpSocket *>(sender());// 在调试输出中打印 "client out!"qDebug() << "client out!";// 在文本编辑器中插入文本,表明客户端已断开连接ui->textEditRev->insertPlainText("客户端断开!");// 计划在事件循环的末尾删除这个 QTcpSocket 对象tmpSock->deleteLater();
}
当 QTcpSocket 的连接状态发生变化时,stateChanged信号会被发出 参数 socketState当前的套接字状态
//当 QTcpSocket 的连接状态发生变化时,stateChanged信号会被发出 参数 socketState当前的套接字状态
void Widget::mstateChanged(QAbstractSocket::SocketState socketState)
{//用于存储组合框中对应端口号的索引int tmpIndex;//将发出信号的对象转换为 QTcpSocket 指针QTcpSocket *tmpSock = qobject_cast<QTcpSocket *>(sender());//使用 qDebug() 打印当前套接字的状态qDebug() << "client out In state:" << socketState;//根据传入的套接字状态 socketState 进行条件判断switch(socketState){//当套接字处于未连接状态时 表示客户端已断开连接case QAbstractSocket::UnconnectedState:ui->textEditRev->insertPlainText("客户端断开!");// 从组合框中移除对应的端口号项tmpIndex = ui->comboBoxChildren->findText(QString::number(tmpSock->peerPort()));ui->comboBoxChildren->removeItem(tmpIndex);// 删除 QTcpSocket 对象tmpSock->deleteLater();// 检查组合框中是否还有该项if(ui->comboBoxChildren->count() == 0)// 禁用发送按钮ui->btnSend->setEnabled(false);break;//当套接字处于已连接 表示有新的客户端接入case QAbstractSocket::ConnectedState://当套接字处于正在连接状态时 表示有新的客户端接入case QAbstractSocket::ConnectingState:ui->textEditRev->insertPlainText("客户端接入!");break;}
}
当点击通信协议和服务器ip地址的复选框值会发送信号触发mComboBox_refresh函数
//当点击通信协议和服务器ip地址的复选框值会发送信号触发mComboBox_refresh函数
void Widget::mComboBox_refresh()
{// 清除组合框中的所有项 ui->comboBoxChildren->clear();// 使用 findChildren 方法获取服务器对象中所有的 QTcpSocket 子对象 QList<QTcpSocket*> tcpSocketClients = server->findChildren<QTcpSocket*>();// 遍历所有找到的 QTcpSocket 对象for(QTcpSocket* tmp:tcpSocketClients){// 检查对象是否为空if(tmp!=nullptr)// 如果对象不为空,将其对应的端口号添加到组合框中ui->comboBoxChildren->addItem(QString::number(tmp->peerPort()));}// 在组合框中添加 "all" 项ui->comboBoxChildren->addItem("all");
}
监听按钮
//监听按钮
void Widget::on_btnListen_clicked()
{// 从界面上的lineEditPort控件获取用户输入的端口号,并将其转换为整数int port = ui->lineEditPort->text().toInt();// 尝试在指定的地址和端口上启动服务器监听if(!server->listen(QHostAddress(ui->comboBoxAddr->currentText()),port)){qDebug() << "listenError";QMessageBox msgBox;// 创建一个消息框对象msgBox.setWindowTitle("监听失败"); // 设置消息框的标题 msgBox.setText("端口号被占用"); // 设置消息框的文本内容 msgBox.exec(); // 显示消息框 return;}// 如果监听成功,则禁用“开始监听”按钮,启用“停止监听”和“断开”按钮 ui->btnListen->setEnabled(false);ui->btnLineout->setEnabled(true);ui->btnStopListen->setEnabled(true);
}
发送按钮
//发送按钮
void Widget::on_btnSend_clicked()
{// 获取所有已连接的QTcpSocket对象QList<QTcpSocket*> tcpSocketClients = server->findChildren<QTcpSocket*>();// 如果没有已连接的客户端if(tcpSocketClients.isEmpty()){// 显示一个错误消息框,告知用户当前没有连接 QMessageBox msgBox;msgBox.setWindowTitle("发送错误!");msgBox.setText("当前无连接!");msgBox.exec();// 禁用发送按钮,避免用户重复点击ui->btnSend->setEnabled(false);return;}//当用户不选择向all,所有客户端进行发送的时候if(ui->comboBoxChildren->currentText() != "all"){// 如果用户没有选择"all",则获取当前选中的客户端名称QString currentName = ui->comboBoxChildren->currentText();// 遍历所有已连接的客户端for(QTcpSocket* tmp : tcpSocketClients){// 检查当前客户端的端口号是否与选中的名称匹配if(QString::number(tmp->peerPort()) == currentName){// 如果匹配,则向该客户端发送数据tmp->write(ui->textEditSend->toPlainText().toStdString().c_str());}}}else{//遍历所有子客户端,并一一调用write函数,向所有客户端发送//遍历所有已连接的客户端for(QTcpSocket* tmp:tcpSocketClients){// 将要发送的文本转换为本地8位编码的QByteArrayQByteArray sendData = ui->textEditSend->toPlainText().toLocal8Bit();// 向每个客户端发送数据 tmp->write(sendData);}}
}
停止监听按钮
//停止监听按钮
void Widget::on_btnStopListen_clicked()
{// 获取所有与server关联的QTcpSocket对象QList<QTcpSocket*> tcpSocketClients = server->findChildren<QTcpSocket*>();// 遍历所有客户端套接字,并关闭它们for(QTcpSocket* tmp:tcpSocketClients){tmp->close();}// 关闭服务器server->close();// 启用“监听”按钮,使其可以再次被点击ui->btnListen->setEnabled(true);ui->btnLineout->setEnabled(false);ui->btnStopListen->setEnabled(false);}
断开按钮
//断开按钮
void Widget::on_btnLineout_clicked()
{// 停止监听按钮on_btnStopListen_clicked();// 释放服务器内存delete server;// 关闭当前窗口this->close();
}
相关文章:
qt学习:网络调试助手客户端+服务端
目录 客户端 步骤 ui界面配置编辑 添加头函数,类成员数据,类成员函数 添加模块 构造函数 连接按钮 收到来自服务器的数据触发 发送按钮 断开按钮 向textEditRev文本编辑器中插入指定颜色的文本 服务端 步骤 ui界面配置 添加头函数&…...
C语言拾遗
函数的地址传递: 函数体内部想要修改函数体外部变量值的时候,使用地址传递 int set(int *pa) {//功能 } int main(void) {int a0;set(&a);//此时a的值经过set函数的修改,且传递到了main函数 } 函数体内想修改函数体外部指针的值的时候…...
大唐杯学习笔记:Day4
1.1NR帧结构 5G NR中,依然采用一帧10ms,并将一帧分为10子帧,每个子帧为1ms。每个子帧包含几个时隙(slot),每个时隙由14个OFDM符号构成(在常规CP下)。 μ \mu μ Δ f 2 μ ∗ 15 [ K H Z ] \Delta f2^{\mu}*15[KHZ] Δf2μ∗15[KHZ]Cyclic prefix015Normal130Normal260Normal…...
docker基线安全修复和容器逃逸修复
一、docker安全基线存在的问题和修复建议 1、将容器的根文件系统挂载为只读 修复建议: 添加“ --read-only”标志,以允许将容器的根文件系统挂载为只读。 可以将其与卷结合使用,以强制容器的过程仅写入要保留的位置。 可以使用命令&#x…...
ZooKeeper概述
ZooKeeper是一个开源的分布式协调服务,由Apache Software Foundation维护。它主要用于解决分布式应用中遇到的一些最常见问题,如命名服务、状态同步、配置管理和群集管理等。通过提供一套简单但强大的API,ZooKeeper使得从简单的锁服务到复杂的…...
【sgCollapseBtn】自定义组件:底部折叠/展开按钮
特性: 支持自定义折叠状态支持自定义标签名称 sgCollapseBtn源码 <template><div :class"$options.name" click"show !show" :placement"placement"><div class"collapse-btns"><div class"c…...
如何根据玩家数量和游戏需求选择最合适的服务器配置?
根据玩家数量和游戏需求选择最合适的服务器配置,首先需要考虑游戏的类型、玩家数量、预计的在线时间以及对内存和CPU性能的需求综合考虑。对于大型多人在线游戏,如MMORPG或MOBA等,由于需要更多的CPU核心数来支持更复杂的游戏逻辑和处理大量数…...
问题解决:各版本的vc_redist下载地址 缺少msvcr100.dll、msvcr120.dll、msvcr140.dll
Visual C Redistributable for Visual Studio各版本的官方链接。解决缺少msvcr100.dll、msvcr120.dll、msvcr140.dll的问题。 下面全部为官方链接: Microsoft Visual C Redistributable 2019 x86: https://aka.ms/vs/16/release/VC_redist.x86.exe x64: https://ak…...
182基于matlab的半监督极限学习机进行聚类
基于matlab的半监督极限学习机进行聚类,基于流形正则化将 ELM 扩展用于半监督,三聚类结果可视化输出。程序已调通,可直接运行。 182matlab ELM 半监督学习 聚类 模式识别 (xiaohongshu.com)...
C语言数组案例编程
1. 编写一个程序实现:从键盘输入15个整数存入数组,然后统计其中正整数的个数。 【要求】采用函数编程 #include<stdio.h> void input(int a[],int n) {int i; for(i0;i<n;i)scanf("%d",&a[i]); }int positiveNum(int a[],int n…...
NLP - 依存句法分析、句子歧义
1. 语言结构的两种观点 Constituency phrase struct grammar context-free grammars(CFGs)Dependency structure 对于context-free grammars(CFGs) 短语结构(Constituency):短语结构语法是一种描述语言结构的方法,它将句子划…...
vue实现图片上传至oss,返回url插入数据库,最后在前端页面上回显图片
vue前端上传图像 上传图片 使用上传图片的upload组件 <el-form-item label"设备图像"><el-upload//设置class样式class"avatar-uploader"//绑定上传路径:action"uploadUrl"//携带token值:headers"tokenInfo":show-file-lis…...
C++学习笔记:set和map
set和map set什么是setset的使用 关联式容器键值对 map什么是mapmap的使用map的插入方式常用功能map[] 的灵活使用 set 什么是set set是STL中一个底层为二叉搜索树来实现的容器 若要使用set需要包含头文件 #include<set>set中的元素具有唯一性(因此可以用set去重)若用…...
990-28产品经理:Different types of IT risk 不同类型的IT风险
Your IT systems and the information that you hold on them face a wide range of risks. If your business relies on technology for key operations and activities, you need to be aware of the range and nature of those threats. 您的IT系统和您在其中持有的信息面临…...
wpa_supplicant与用户态程序的交互分析
1 wpa_supplicant与用户态程序wpa_cli的交互过程 1.1 交互接口类型 wpa_supplicant与用户态程序交互的主要接口包括以下几种: 1)命令行界面:通过命令行工具 wpa_cli 可以与 wpa_supplicant 进行交互。wpa_cli 允许用户执行各种 wpa_suppli…...
JavaScript继承 寄生组合式继承 extends
JavaScript继承 1、JS 的继承到底有多少种实现方式呢? 2、ES6 的 extends 关键字是用哪种继承方式实现的呢? 继承种类 原型链继承 function Parent1() {this.name parentlthis.play [1, 2, 3] }function Child1() {this.type child2 }Child1.prototype new Parent1(…...
Nginx 和Tomcat比较
Nginx和Tomcat是两种不同的技术,它们在应用场景、性能、动态处理能力等方面有所区别: 应用场景 Nginx通常用作静态内容服务器或代理服务器,可以将外部请求转发给其他应用服务器,如Tomcat、Django等。而Tomcat则主要用作应用服…...
p18 线性代数,行阶梯型矩阵
行阶梯型矩阵 行最简型矩阵...
leetcode—— 动态规划—— 零钱兑换
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无限的。 示…...
java面试题(spring框架篇)(黑马 )
树形图: 一、Spring框架种的单例bean是线程安全吗? Service Scope("singleton") public class UserServiceImpl implements UserService{ } singleton:bean在每个Spring IOC容器中只有一个实例 protype:一个bean的定义可以有多个…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
