QT开发--网络编程

news2025/2/28 17:36:31

第十七章 QT网络编程

        Qt Network模块用于TCP/IP编程,提供HTTP请求、cookies、DNS等功能的C++类。

        使用需在pro文件中添加“QT += network”

tcp通信流程图

17.1 QHostInfo

        QHostInfo类用于查找主机名与IP地址的关联。它提供两种查找方式:

        1、异步查找:调用lookupHost(),传入主机名或IP地址、接收对象和槽。

        查找完成时,槽被调用,结果存储在QHostInfo对象中。

QHostInfo::lookupHost("www.baidu.com", // 主机名或IP地址  
                     this, // 接收查找结果的接收者对象  
                     [](const QHostInfo& info) // 处理查找结果的lambda表达式  
{    
    qDebug() << info.hostName() << info.addresses();  // 输出主机名和IP地址列表  
});

        ‌一个主机名可以有多个关联的IP地址,这是因为DNS系统允许一个主机名映射到多个IP地址。‌ 这种机制称为域名解析冲突,它允许在特定情况下,一个主机名对应多个IP地址‌ 。

​​​​​​​"www.baidu.com"                                 //域名
(QHostAddress("180.101.50.242"),                 //IPV4地址
QHostAddress("180.101.50.188"), 
QHostAddress("240e:e9:6002:15a:0:ff:b05c:1278"),  //ipv6地址
QHostAddress("240e:e9:6002:15c:0:ff:b015:146f")) 

        2、阻塞查找:使用QHostInfo::fromName()函数。

QHostInfo info = QHostInfo::fromName("smtp.qq.com");  
qDebug() << info.hostName() << info.addresses();

        查找失败时,可使用error()errorString()获取错误详情。支持国际化域名(IDNs)。

        要检索本地主机名,使用QHostInfo::localHostName()

17.2 QHostAddress

        QHostAddress类用于保存和操作IPv4或IPv6地址,独立于平台和协议。

        它通常与QTcpSocketQTcpServerQUdpSocket结合使用,以支持网络连接。

        该类提供设置和检索主机地址的方法,如setAddress()、toIPv4Address()、toIPv6Address()和toString(),以及检查地址类型的protocol()方法。

        QHostAddress还定义了一组预定义地址,包括:

枚举描述
QHostAddress::Null空地址对象
QHostAddress::LocalHostIPv4本地主机地址(127.0.0.1)
QHostAddress::localhsotIPv6IPv6本地主机地址(::1)。
QHostAddress::BroadcastIPv4广播地址(255.255.255.255)。
QHostAddress::AnyIPv4IPv4任何地址(0.0.0.0),绑定此地址的套接字仅在IPv4接口上监听。
QHostAddress::AnyIPv6IPv6任何地址(::),绑定此地址的套接字仅在IPv6接口上监听。
QHostAddress::Any双栈任意地址,绑定此地址的套接字将侦听IPv4和IPv6接口。

17.3 QNetworkInterface

        QNetworkInterface类提供了获取主机IP地址和网络接口列表的功能

        每个网络接口可能包含多个IP地址,以及相关的网络掩码和广播地址,这些信息可通过addressEntries()获取。

        若只需IP地址,可使用allAddresses()

        hardwareAddress()用于获取接口的硬件地址。

/*获取主机上所有ip地址*/
QList<QHostAddress> addrList = QNetworkInterface::allAddresses();  
for (const QHostAddress &addr : addrList) {  
    qDebug() << addr.protocol() << addr.toString();  
}
/*获取并遍历主机上所有网络接口*/
QList<QNetworkInterface> networkList = QNetworkInterface::allInterfaces();  
for (const QNetworkInterface &inter : networkList) {  
    if (!inter.isValid()) continue;  
      
    qDebug() << inter.name() << inter.type() << inter.hardwareAddress() << inter.humanReadableName();  
      
    for (const QNetworkAddressEntry &entry : inter.addressEntries()) {  
        qDebug() << entry.ip();  
    }  
}

17.4 QNetworkAddressEntry

        QNetworkAddressEntry类用于存储网络接口上的IP地址及其相关的网络掩码和广播地址

        关键成员函数包括:

        broadcast():返回与IPv4地址和子网掩码相关联的广播地址

        ip():返回网络接口中的IPv4或IPv6地址

        netmask():返回与IP地址相关联的子网掩码

QNetworkAddressEntry entry;  // 假设entry已经被正确初始化  
  
QHostAddress ip = entry.ip();                  //获取Ip地址
QHostAddress netmask = entry.netmask();        //获取子网掩码
QHostAddress broadcast = entry.broadcast();    //获取广播地址
  
qDebug() << "IP:" << ip.toString();  
qDebug() << "Netmask:" << netmask.toString();  
qDebug() << "Broadcast:" << broadcast.toString();

17.5 QAbstractSocket

        QAbstractSocket类QTcpSocketQUdpSocket提供了通用的套接字功能

1. QAbstractSocket基类

        是QTcpSocketQUdpSocket的基类,统一了API。

2. 套接字选择

        可以直接实例化QTcpSocketQUdpSocket

#include <QCoreApplication>  
#include <QTcpSocket>  
#include <QDebug>  
  
int main(int argc, char *argv[])  
{  
    QCoreApplication app(argc, argv);  
  
    // 创建一个QTcpSocket实例  
    QTcpSocket *socket = new QTcpSocket();  
  
    // 连接到服务器(这里使用localhost和端口12345作为示例)  
    socket->connectToHost("127.0.0.1", 12345);  
  
    // 监听连接状态改变信号  
    QObject::connect(socket, &QTcpSocket::connected, []() {  
        qDebug() << "Connected to server";  
          
        // 在连接成功后发送数据(这里发送一个简单的Hello消息)  
        socket->write("Hello, server!\n");  
    });  
  
    // 监听数据可读信号  
    QObject::connect(socket, &QTcpSocket::readyRead, []() {  
        qDebug() << "Data received from server:" << socket->readAll();  
    });  
  
    // 监听连接断开信号(可选)  
    QObject::connect(socket, &QTcpSocket::disconnected, []() {  
        qDebug() << "Disconnected from server";  
          
        // 在这里可以执行一些清理操作,比如删除socket对象(如果不再需要)  
        // 注意:如果socket对象是在局部作用域内创建的(例如在这个main函数中),  
        // 并且你没有将其传递给其他长期存在的对象或线程,那么当main函数结束时,  
        // socket对象将被自动释放(前提是你没有使用new来动态分配它)。  
        // 但是,如果你在其他地方创建了socket对象并希望在这里删除它,  
        // 你应该确保没有其他地方还在使用这个对象。  
    });  
  
    // 进入Qt的事件循环(对于控制台应用程序,这一步是必需的,以便处理信号和槽)  
    return app.exec();  
}

        或者使用本机套接字描述符,创建QAbstractSocket实例,并调用setSocketDescriptor()

#include <QTcpSocket>  
#include <QSocketNotifier>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
#include <unistd.h>  
#include <QDebug>  
  
int main(int argc, char *argv[])  
{  
    // 初始化Qt应用程序(对于非GUI应用程序,这一步可能不是必需的,但在这里包含以防万一)  
    QCoreApplication app(argc, argv);  
  
    // 创建一个本机套接字描述符(这里仅作示例,实际代码中你可能需要在其他地方创建和配置这个套接字)  
    int nativeSocketDescriptor = socket(AF_INET, SOCK_STREAM, 0);  
    if (nativeSocketDescriptor == -1) {  
        qCritical() << "Failed to create native socket descriptor";  
        return -1;  
    }  
  
    // 配置套接字地址和端口(这里使用localhost和任意端口作为示例)  
    sockaddr_in serverAddress;  
    serverAddress.sin_family = AF_INET;  
    serverAddress.sin_port = htons(12345); // 任意端口,应根据实际情况修改  
    inet_pton(AF_INET, "127.0.0.1", &serverAddress.sin_addr); // localhost  
  
    // 连接到服务器(这里仅作示例,实际代码中你可能需要处理连接失败的情况)  
    if (connect(nativeSocketDescriptor, (sockaddr*)&serverAddress, sizeof(serverAddress)) == -1) {  
        qCritical() << "Failed to connect to server";  
        close(nativeSocketDescriptor);  
        return -1;  
    }  
  
    // 创建一个QTcpSocket实例(也可以使用QUdpSocket,取决于你的需求)  
    QTcpSocket *socket = new QTcpSocket();  
  
    // 将本机套接字描述符设置为QTcpSocket的底层套接字描述符  
    if (!socket->setSocketDescriptor(nativeSocketDescriptor)) {  
        qCritical() << "Failed to set socket descriptor";  
        delete socket;  
        return -1;  
    }  
  
    // 现在你可以像使用普通的QTcpSocket一样使用这个套接字了  
    // 例如,监听连接状态改变、数据可读等信号,并相应地处理它们  
  
    // 监听连接状态改变(可选)  
    QObject::connect(socket, &QTcpSocket::stateChanged, [](int state) {  
        qDebug() << "Socket state changed:" << state;  
    });  
  
    // 监听数据可读(可选)  
    QObject::connect(socket, &QTcpSocket::readyRead, []() {  
        qDebug() << "Data available:" << socket->readAll();  
    });  
  
    // ... 在这里执行其他操作,例如发送数据、关闭连接等 ...  
  
    // 注意:在Qt应用程序结束时,确保正确地删除并释放所有动态分配的对象和资源  
    // 在这个例子中,由于我们在main函数中创建了socket对象,并且没有在其他地方删除它,  
    // 因此当main函数结束时,socket对象将被自动释放(前提是我们没有将其传递给其他长期存在的对象或线程)。  
    // 然而,在实际的应用程序中,你可能需要更仔细地管理对象的生命周期。  
  
    return app.exec(); // 对于非GUI应用程序,这一步可能不是必需的;但如果你的应用程序有事件循环,则需要调用它  
}

3. 协议差异

  • TCP:可靠、面向流、面向连接。
  • UDP:不可靠、面向数据报、无连接。
  • QAbstractSocket通过connectToHost()为UDP提供虚拟连接。

4. 状态管理

  • 初始状态:UnconnectedState。
  • 连接过程:HostLookupState -> ConnectingState -> ConnectedState。
    •                 //查找主机->请求连接->连接成功
  • 错误处理:触发error()。
  • 状态改变:触发stateChanged()。

5. 数据读写

  • 读取:read()、readLine()、readAll()。
  • 写入:write()。
  • 信号:bytesWritten()。
  • 缓冲区:setReadBufferSize()限制大小。

6. 连接管理

  • 关闭连接:disconnectFromHost()
  • 立即中止:abort()
  • 远程关闭:发出RemoteHostClosedError,然后disconnected()。

7. 对等方信息

peerPort()     //返回连接的对等端(远程)的端口号。  
peerAddress()  //返回连接的对等端(远程)的IP地址。  
peerName()     //返回连接的对等端(远程)的名称,通常是IP地址和端口号的组合。  
  
localPort()    //返回本地套接字的端口号。  
localAddress() //返回本地套接字的IP地址。

8. 阻塞函数

waitForConnected()    // 阻塞当前线程,直到套接字连接成功或超时。  
waitForReadyRead()    // 阻塞当前线程,直到有数据可读或超时。  
waitForBytesWritten() // 阻塞当前线程,直到所有待发送的数据都已写入套接字或超时。  
waitForDisconnected() // 阻塞当前线程,直到套接字断开连接或超时。

17.6 信号

自定义信号

  1. connected() - 成功建立连接后发出。
  2. disconnected() - 套接字断开连接时发出。
  3. error(QAbstractSocket::SocketError socketError) - 发生错误时发出,带有错误类型。
  4. hostFound() - 主机查找成功后发出。
  5. *proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator authenticator) - 需要代理身份验证时发出。
  6. stateChanged(QAbstractSocket::SocketState socketState) - 套接字状态变化时发出,带有新状态。//查找->请求连接->连接建立。

从QIODevice继承的信号

  1. aboutToClose() - 设备即将关闭时发出。
  2. bytesWritten(qint64 bytes) - 向设备写入数据时发出,带有写入的字节数。
  3. readChannelFinished() - 输入流关闭时发出。
  4. readyRead() - 有新数据可读时发出。

从QObject继承的信号

  1. *destroyed(QObject obj = Q_NULLPTR) - 对象销毁前发出。
  2. objectNameChanged(const QString &objectName) - 对象名称更改后发出。

17.7 QTcpServer(监听套接字)

        QTcpServer类是一个基于TCP的服务器类,用于监听并接收传入的TCP连接。

功能概述

  • 监听端口:可以指定端口或自动选择。
  • 监听地址:可以监听特定地址或所有地址。
  • 开始监听:调用listen()方法。
  • 连接信号:每当有新连接时,发出newConnection()信号。
  • 接受连接:调用nextPendingConnection()获取已连接的QTcpSocket
  • 错误处理:使用serverError()errorString()处理错误。
  • 获取信息:使用serverAddress()serverPort()获取监听信息。
  • 停止监听:调用close()方法。
  • 无事件循环:可使用waitForNewConnection()阻塞等待连接。

        listen()本身是非阻塞的,它不会等待连接,而是立即返回。连接的处理是通过信号和槽机制异步完成的。

               waitForNewConnection()方法用于在没有事件循环的情况下,阻塞当前线程直到有新的连接进来或者超时发生。

信号

  • acceptError(QAbstractSocket::SocketError socketError):接受新连接出错时发出
  • newConnection()有新连接可用时发出
// 创建服务器实例  
QTcpServer *server = new QTcpServer(this);  
  
// 监听指定端口(例如1234)  
server->listen(QHostAddress::Any, 1234);  
  
// 连接newConnection信号到槽函数  
connect(server, &QTcpServer::newConnection, this, &MyClass::handleNewConnection);  
  
// 槽函数,处理新连接  
void MyClass::handleNewConnection() {  
    QTcpSocket *clientSocket = server->nextPendingConnection();  
    // 使用clientSocket与客户端通信  
}  
  
// 可选:处理接受错误  
connect(server, &QTcpServer::acceptError, this, &MyClass::handleAcceptError);  
void MyClass::handleAcceptError(QAbstractSocket::SocketError socketError) {  
    // 处理错误,例如记录日志或显示错误信息  
}

17.8 QTcpSocket(通信套接字)

        TCP是一种面向数据流和连接的可靠传输协议,HTTP和FTP等协议都是基于TCP协议的。

        QTcpSocket类继承自QAbstractSocket,用于传输连续的数据流,适合连续数据传输。

        它分为客户端和服务端,即C/S模型。

        QTcpSocket提供读写两个独立的数据流,通过read()write()操作控制。

        读取前可使用bytesAvailable()检查数据是否足够。

        QTcpServer用于处理客户端连接,通过listen()监听连接请求,并在有客户端连接时发出newConnection()信号,可使用QTcpSocket读取客户端数据。

        QIODevice类提供了几个用于读写数据的常用公有函数。

读取函数

/*从设备读取最多maxSize字节到data中,返回读取到的字节数*/
qint64 read(char *data, qint64 maxSize);

/*从设备读取最多maxSize字节,返回QByteArray。*/
QByteArray read(qint64 maxSize);

/*从设备读取所有剩余数据,返回QByteArray*/
QByteArray readAll();

写入函数

/*写入最多maxSize字节的数据到设备中。
  返回实际写入的字节数,出错时返回-1。*/
qint64 write(const char *data, qint64 maxSize);

/*写入以零结尾的8位字符字符串到设备中。
  返回实际写入的字节数,出错时返回-1。*/
qint64 write(const char *data);

/*写入QByteArray的内容到设备中。
  返回实际写入的字节数,出错时返回-1。*/
qint64 write(const QByteArray &byteArray);

17.9 TCP聊天程序

/*服务端*/
#include "mainwindow.h"  // 包含MainWindow类的头文件  
#include "ui_mainwindow.h"  // 包含UI类的头文件,用于设置UI界面  
  
// MainWindow类的构造函数,初始化窗口和服务器  
MainWindow::MainWindow(QWidget *parent)  
    : QMainWindow(parent)  
    , ui(new Ui::MainWindow)  // 初始化UI对象  
{  
    ui->setupUi(this);  // 设置UI界面  
    server = new QTcpServer(this);  // 创建QTcpServer对象  
    // 连接服务器的newConnection信号到MainWindow的onNewConnection槽函数  
    connect(server, &QTcpServer::newConnection, this, &MainWindow::onNewConnection);  
    startServer();  // 启动服务器  
}  
  
// MainWindow类的析构函数,释放UI对象  
MainWindow::~MainWindow()  
{  
    delete ui;  
}  
  
// 启动服务器的方法  
void MainWindow::startServer() {  
    // 尝试在任意地址的1234端口上监听连接  
    if(server->listen(QHostAddress::Any, 1234)) {  
        ui->textEdit->append("Server started on port 1234");  // 服务器启动成功,显示消息  
    } else {  
        ui->textEdit->append("Error: Could not start server");  // 服务器启动失败,显示错误消息  
    }  
}  
  
// 处理新连接的方法  
void MainWindow::onNewConnection() {  
    QTcpSocket *clientSocket = server->nextPendingConnection();  // 获取待处理的客户端连接  
    // 连接客户端的readyRead信号到MainWindow的onReadyRead槽函数  
    connect(clientSocket, &QTcpSocket::readyRead, this, &MainWindow::onReadyRead);  
    // 连接客户端的disconnected信号到MainWindow的onDisconnected槽函数  
    connect(clientSocket, &QTcpSocket::disconnected, this, &MainWindow::onDisconnected);  
    clientSockets << clientSocket;  // 将客户端连接添加到客户端列表  
}  
  
// 处理客户端发送数据的方法  
void MainWindow::onReadyRead() {  
    QTcpSocket *clientSocket = qobject_cast<QTcpSocket *>(sender());  // 获取发送数据的客户端连接  
    QString message = clientSocket->readAll();  // 读取客户端发送的数据  
    ui->textEdit->append(message);  // 在文本编辑器中显示接收到的消息  
}  
  
// 处理客户端断开连接的方法  
void MainWindow::onDisconnected() {  
    QTcpSocket *clientSocket = qobject_cast<QTcpSocket *>(sender());  // 获取断开连接的客户端连接  
    clientSockets.removeAll(clientSocket);  // 从客户端列表中移除断开的连接  
    clientSocket->deleteLater();  // 稍后删除客户端连接对象  
}
/*客户端*/
#include "mainwindow.h"  // 包含MainWindow类的头文件  
#include "ui_mainwindow.h"  // 包含UI类的头文件,用于设置UI界面  
  
// MainWindow类的构造函数,初始化窗口和套接字  
MainWindow::MainWindow(QWidget *parent)  
    : QMainWindow(parent)  
    , ui(new Ui::MainWindow)  // 初始化UI对象  
{  
    ui->setupUi(this);  // 设置UI界面  
    socket = new QTcpSocket(this);  // 创建QTcpSocket对象  
    // 连接按钮的clicked信号到MainWindow的onSendMessage槽函数  
    connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::onSendMessage);  
    // 尝试连接到本地服务器的1234端口  
    socket->connectToHost("127.0.0.1", 1234);  
    // 连接套接字的connected信号到MainWindow的onConnected槽函数  
    connect(socket, &QTcpSocket::connected, this, &MainWindow::onConnected);  
}  
  
// MainWindow类的析构函数,释放UI对象  
MainWindow::~MainWindow()  
{  
    delete ui;  
}  
  
// 发送消息的方法  
void MainWindow::onSendMessage() {  
    // 检查套接字是否处于连接状态  
    if(socket->state() == QAbstractSocket::ConnectedState) {  
        // 发送输入框中的文本到服务器,并在末尾添加换行符  
        socket->write(ui->lineEdit->text().toUtf8() + "\n");  
    }  
    ui->lineEdit->clear();  // 清空输入框  
}  
  
// 处理连接成功的方法  
void MainWindow::onConnected() {  
    // 在文本编辑器中显示连接成功的消息  
    ui->textEdit->append("Connected to server");  
}
客户端发消息,服务端接收

17.9 QUdpSocket(通信套接字) 

        UDP是轻量级、不可靠、无连接的协议,适用于非关键传输。

        QUdpSocket类用于发送和接收UDP数据报,通过IP地址和端口号实现应用间通信。它支持IPv4广播,数据报建议小于512字节,端口号选1024-65535。

  1. MTU限制
    • MTU(Maximum Transmission Unit,最大传输单元):以太网中MTU通常设置为1500字节。当IP层的数据包(包括IP头和数据)超过MTU时,需要进行分片传输。分片会增加传输的复杂性和出错的可能性。
    • IP头和UDP头开销:IP头通常需要20字节,UDP头需要8字节。因此,对于UDP数据报,实际可用的数据负载空间会减少。
    • 避免分片:为了确保UDP数据报不需要分片,建议其大小小于或等于MTU减去IP头和UDP头的开销,即1500 - 20 - 8 = 1472字节。然而,考虑到网络中的不确定性(如路径上的MTU可能小于1500字节),以及可能的IP选项或其他封装开销,512字节通常被认为是一个更安全的上限。
  1. 保留端口号
    • 0-1023:这些端口号被保留给系统或知名应用程序使用,如FTP(21)、Telnet(23)、DNS(53)等。普通用户或应用程序不应使用这些端口号,以避免冲突。
  2. 动态端口号范围
    • 1024-65535:这些端口号被分配给用户进程或应用程序使用。当客户端或服务器需要建立连接时,它们可以从这个范围内选择一个未使用的端口号进行通信。
    • 灵活性:选择1024-65535范围内的端口号可以确保通信的灵活性,因为这些端口号在大多数操作系统和网络环境中都是可用的。

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

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

相关文章

windows10创建系统账户

方式一: .a.点击 windows 图标->设置 .b.点击账户 .c.点击其他账户->将其他人添加到这台电脑->弹出对话框 .d.选中用户->右键->新用户->输入用户名和密码->创建 如下创建完成 方式二&#xff1a; windows R 输入lusrmgr.msc 后续操作步骤同上。 修改用…

YOLO11改进|SPPF篇|引入FocalModulation特征金字塔

目录 一、【FocalModulation】特征金字塔1.1【FocalModulation】特征金字塔介绍1.2【FocalModulation】核心代码二、添加【FocalModulation】特征金字塔2.1STEP12.2STEP22.3STEP32.4STEP4三、yaml文件与运行3.1yaml文件3.2运行成功截图一、【FocalModulation】特征金字塔 1.1【…

Linux网络命令:用于配置防火墙规则的一个用户友好的工具ufw详解

目录 一、概述 二、安装 UFW 三、启动、重启和关闭 UFW 1、启动 2、关闭UFW 3、 重启 UFW 四、查看 UFW 状态 五、UFW 基本命令 1. 允许端口 &#xff08;1&#xff09;单个 TCP 端口 &#xff08;2&#xff09;允许单个 UDP 端口 &#xff08;3&#xff0…

MySQL增删改进阶

目录 1.数据库约束 1.1约束类型 1.2 not null约束 1.3 unique&#xff1a;唯一约束 1.4 default&#xff1a;默认约束 1.5 primary key&#xff1a;主键约束 1.6 foreign key:外键约束 1.7 check约束&#xff08;了解&#xff09; 2.表的设计 3.新增&#xff08;进阶&…

CUDA 运行时GPU信息查询

cuda 官网文档名&#xff1a;CUDA_Runtime_API 运行时API查询GPU信息 调用 cudaDeviceProp prop; cudaGetDeviceProperties(&prop, device_id) 定义 由此可见&#xff0c;只能在主机上调用。 #include <cuda_runtime.h>#include <iostream> #include <…

Apache Kafka消息传递策略

kafka消息传递策略 微信公众号&#xff1a;阿俊的学习记录空间小红书&#xff1a;ArnoZhangwordpress&#xff1a;arnozhang1994博客园&#xff1a;arnozhangCSDN&#xff1a;ArnoZhang1994 现在我们了解了一些关于生产者和消费者的工作原理&#xff0c;接下来讨论Kafka在生产…

Java:玩家打怪小游戏

今天&#xff0c;我们尝试用Java来做一个“打怪小游戏”&#xff0c;听名字就知道&#xff0c;我们是应该创建几个成员和怪物&#xff0c;还有知道知道成员和怪物的血量&#xff0c;一次攻击的伤害等等。。当然我们的游戏攻击模式是“回合制”&#xff08;其实是别的方法&#…

SpringCloud-OpenFeign-服务接口调用

是什么 把需要暴露的api使用接口来暴露&#xff0c;客户端需要调用的时候&#xff0c;直接查看这个接口中有没有就可以了 通用步骤 架构说明 common模块 common 引入 openfeign 新建服务接口类 FeignClient(value "cloud-payment-service") // 服务名 public i…

【数据采集工具】Flume从入门到面试学习总结

国科大学习生活&#xff08;期末复习资料、课程大作业解析、大厂实习经验心得等&#xff09;: 文章专栏&#xff08;点击跳转&#xff09; 大数据开发学习文档&#xff08;分布式文件系统的实现&#xff0c;大数据生态圈学习文档等&#xff09;: 文章专栏&#xff08;点击跳转&…

# linux从入门到精通-从基础学起,逐步提升,探索linux奥秘(十三)--权限设置注意事项和属主属组设置sudo操作

linux从入门到精通-从基础学起&#xff0c;逐步提升&#xff0c;探索linux奥秘&#xff08;十三&#xff09;–权限设置注意事项和属主属组设置sudo操作 一、linux 权限设置 特殊注意事项 1、使用root用户创建一个文件夹&#xff08;/oo&#xff09;&#xff0c;权限默认&…

前端知识点总和

目录 一、canvas&#xff1a; &#xff08;1&#xff09;创建canvas标签&#xff1a; &#xff08;2&#xff09;使用JS获得这个canvas标签的DOM对象&#xff1a; &#xff08;3&#xff09;决定是画二维还是三维的画&#xff1a; &#xff08;4&#xff09;API&#xff1…

企业防止信息泄露的措施有哪些?10个防止信息泄露小技巧分享给你

在数字化时代&#xff0c;企业面临的安全挑战日益严峻&#xff0c;尤其是信息泄露问题。一旦企业内部或外部的敏感信息遭到泄露&#xff0c;不仅会造成巨大的经济损失&#xff0c;还可能影响企业声誉、客户信任&#xff0c;甚至可能引发法律纠纷。为了有效防止信息泄露&#xf…

使用 SQLmap 自动化检测 SQL 注入

使用 SQLmap 自动化检测 SQL 注入是一种常见的渗透测试技术。SQLmap 是一个强大的开源工具&#xff0c;可以自动检测和利用 SQL 注入漏洞&#xff0c;提取数据库信息&#xff0c;并接管目标数据库服务器。下面是如何使用 SQLmap 进行自动化检测 SQL 注入的基本步骤。 准备环境…

RabbitMQ 入门(七)SpringAMQP五种消息类型

一、Topic Exchange&#xff08;消息模式&#xff09; TopicExchange 与DirectExchange类似&#xff0c;区别在于routingKey可以是多个单词的列表&#xff0c;并且以.分割。 Topic类型的Exchange与Direct相比&#xff0c;都是可以根据RoutingKey把消息路由到不同的队列。只不过…

Spring WebFlux 核心原理(2-1)

1、Spring 响应式编程 1.1、早期响应式解决方案 响应式编程是构建响应式系统的主要候选方案。Spring 4.x 引入了 ListenableFuture 类&#xff0c;它扩展了 Java Future&#xff0c;并且可以基于 HTTP 请求实现异步执行操作。但是只有少数 Spring 4.x 组件支持新的 Java 8 Com…

Nginx(Linux):服务器版本升级和新增模块

目录 1、概述2、使用Nginx服务信号完成Nginx升级2.1 备份当前版本的Nginx2.2 向服务器导入新的Nginx2.3 向服务器导入新的Nginx2.4 停止老版本Nginx 3、使用Nginx安装目录的make命令完成升级3.1 备份当前版本的Nginx3.2 向服务器导入新的Nginx3.3 执行更新命令 1、概述 如果想…

24最新ComfyUI插件与Lora的下载及使用指南!

前言 本节我们介绍ComfyUI插件和Lora的下载及使用方式。 1. 安装 1.1 Checkpoint安装 将从前面介绍的模型下载平台下载后&#xff0c;放在ComfyUI/models/checkpoints文件夹下。 所有的AI设计工具&#xff0c;安装包、模型和插件&#xff0c;都已经整理好了&#xff0c;&am…

【vue自定义指令】骨架屏指令

场景 预加载的过程中&#xff0c;数据还未请求到&#xff0c;dom已经渲染出来了&#xff1f; 展示效果 实现 封装指令&#xff08;代码块1&#xff09; app引入&#xff08;代码块2&#xff09;使用&#xff08;代码块3&#xff09; 代码 封装 ​ import { reactive, wa…

Spark全网最全总结

Spark 产生之前&#xff0c;已经有 MapReduce 这类非常成熟的计算系统存在了&#xff0c;并提供 了高层次的 API(map/reduce)&#xff0c;把计算运行在集群中并提供容错能力&#xff0c;从而实现 分布式计算。 虽然 MapReduce 提供了对数据访问和计算的抽象&#xff0c…

一个月学会Java 第13天 抽象类与接口

Day13 抽象类与接口 通过了前面的学习&#xff0c;我们已经掌握了面向对象的基础 继承 封装 多态 第一章 抽象类 接下来&#xff0c;我们要对面向对象学习高级的部分&#xff0c;我们先要学到的就是抽象类&#xff0c;听名字也能想到&#xff0c;肯定很抽象&#xff0c;那我们先…