[Qt's QNetworkAccessManager] Overview and examples

Overview

QNetworkAccessManager类Allows an application to send network requests and receive responses
网络访问API is built around an QNetworkAccessManager对象 object that holds common configuration and settings for the requests it sends . It contains proxy and cache configuration, as well as signals related to such issues, as well as reply signals that can be used to monitor the progress of network operations. For an entire Qt application, one QNetworkAccessManager should be enough.
Once the QNetworkAccessManager object is created, the application can use it to send requests over the network. A set of standard functions are provided that accept a request and optional data, each returning a QNetworkReply对象. The returned object is used to obtain any data returned in response to the corresponding request.
Here is a simple example:

    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    connect(manager, &QNetworkAccessManager::finished,
            this, [=](QNetworkReply* reply){
    
    
        ui->textBrowser->append(QString(reply->readAll()));
    });

    manager->get(QNetworkRequest(QUrl("http://qt-project.org")));

Nowget()After completion, contact the meetingQNetworkAccessManager::finishedsignal.
Showing as below:
Insert image description here

QNetworkAccessManagerhas one异步API. When the finished(QNetworkReply*) signal is triggered, the parameter accepted by its corresponding slot function is the QNetworkReply object, which contains the downloaded data and metadata (headers, etc.).

Note: After the request is completed, it should be deleted when appropriateQNetworkReply对象. Do not delete directly in the slot of connectionfinished(). You can use thedeleteLater() function.

reply->deleteLater();

Note:QNetworkAccessManager queues the requests it receives. The number of requests executed in parallel depends on the protocol. Currently, for HTTP协议 on desktop platforms, one host/port combination executes 6 requests in parallel.
Another example, as follows:

    QNetworkAccessManager *manager = new QNetworkAccessManager(this);

    QNetworkRequest request;
    request.setUrl(QUrl("http://qt-project.org"));
    request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");

    QNetworkReply *reply = manager->get(request);
    connect(reply, &QNetworkReply::readyRead, this, [this, reply](){
    
    
        ui->textBrowser->append(QString(reply->readAll()));
    });
    connect(reply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError err)>(&QNetworkReply::error),
            this, [=](QNetworkReply::NetworkError err){
    
    

    });

    connect(reply, &QNetworkReply::sslErrors,
            this, [=](const QList<QSslError> &errors){
    
    

    });

Thisget()After completion, we will returnQNetworkReplyThe first elephant, the first elephant will be touchedQNetworkReply::readyRead,< a i=4>,signal. Showing as below: static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError err)>(&QNetworkReply::error)QNetworkReply::sslErrors

Insert image description here

Why should the aboveerror() signal be written like thisstatic_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError err)>(&QNetworkReply::error)?
is because there is error function overloading, and &QNetworkReply::error does not know which signal is triggered, so it needs to be converted.

Network and roaming support

  1. QNetworkAccessManager’s management capabilities:
    • QNetworkAccessManagerThe ability to manage network connections was gained in Qt version 4.7. This means that it is not just a simple tool for sending network requests, but can also manage the opening and closing of network connections.
  2. 离线启动网口
    • When the device is offline,QNetworkAccessManager can automatically activate the network port to send or receive network requests.
  3. Automatic termination
    • If the current process is the last process to use the uplink, QNetworkAccessManager will automatically close the network port. On some platforms, to ensure resources are released appropriately, the system may maintain a connection for a period of time even after the last application stops using the uplink, but this grace period is taken into account.
  4. Transparent handling of roaming:
    • When a device moves from one network access point to another (for example, from a Wi-Fi network to a mobile data network), QNetworkAccessManager can handle this automatically Switch so that applications do not need to care about network changes.
  5. Automatically transfer network requests:
    • If a device is moved from one network access point to another, any queued or pending network requests are automatically transferred to the new access point. This means that applications do not need to worry about request resending after network changes.
  6. No client changes required:
    • Client applications using QNetworkAccessManager do not require any modifications or changes. This means that developers can simply use this class without worrying about the details of network connection management.
  7. Hiradai dependence:
    • QNetworkAccessManagerNetwork and roaming support in depends on the supported platform. This means that different operating systems or hardware may support this feature to varying degrees.
  8. Kiji characteristics
    • QNetworkConfigurationManager::NetworkSessionRequired is a method that can be used to detect whether QNetworkAccessManager takes advantage of this feature. This can help developers determine if additional processing or tuning is needed for a specific platform.

like:

    QNetworkConfigurationManager nCM;

    qDebug().noquote() << nCM.capabilities();

Insert image description here
All in all, in short, QNetworkAccessManager in Qt 4.7 provides developers with a simpler and more automated way to manage network connections, allowing developers to focus more on applications functions and logic without caring about the underlying details of the network.

Commonly used functions

The following functions were introduced in different Qt versions, so when used, you can consult the help manual of the current version.

Enumeration: enum QNetworkAccessManager::NetworkAccessibility

Indicates whether the network is accessible through this network access manager. It is used to represent the network access status of an application. enum QNetworkAccessManager::NetworkAccessibilityProvides a simple and effective way for Qt applications to detect and respond to changes in network status.

constant value describe
QNetworkAccessManager::UnknownAccessibility -1 Unable to determine network accessibility.
QNetworkAccessManager::NotAccessible 0 The network is not currently accessible because there is currently no network coverage or network access has been explicitly disabled by calling setNetworkAccessible().
QNetworkAccessManager::Accessible 1 The network is reachable.

This enumeration works:

  1. Network status detection: Through this enumeration, the application can query the current network connection status, such as whether it is online, offline, etc.
  2. Network status change notification: When network status changes, QNetworkAccessManager can send signals to notify applications so that they can respond to these changes, e.g. Retry a previously failed network request.
  3. Control network-related features: Based on the current network status, the application can decide whether to enable or disable certain network-related features.

Its usage:

  1. Query network status:
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QNetworkAccessManager::NetworkAccessibility accessibility = manager->networkAccessibility();
  1. Signals connecting network status changes:
    When the network status changes, the networkAccessibleChanged signal will be emitted . You can connect this signal to respond to changes in network status.
connect(manager, &QNetworkAccessManager::networkAccessibleChanged, 
        this, &YourClass::handleNetworkAccessibilityChange);

Then handle changes in network status in the slot function:

void YourClass::handleNetworkAccessibilityChange(QNetworkAccessManager::NetworkAccessibility accessible) {
    
    
    switch (accessible) {
    
    
    case QNetworkAccessManager::UnknownAccessibility:
        // 处理未知状态
        break;
    case QNetworkAccessManager::NotAccessible:
        // 处理不可访问状态
        break;
    case QNetworkAccessManager::Accessible:
        // 处理可访问状态
        break;
    }
}
  1. Decision based on network status:
    Based on the current network status, decide whether to perform certain operations, such as:
if (manager->networkAccessibility() == QNetworkAccessManager::Accessible) {
    
    
    // 执行需要网络连接的操作
} else {
    
    
    // 执行离线操作或提示用户检查网络连接
}
Enumeration:enum QNetworkAccessManager::Operation

Reply to the operation being processed. Used to represent the different types of network operations performed byQNetworkAccessManager.

constant value describe
QNetworkAccessManager::HeadOperation 1 Retrieve header operations (created using head())
QNetworkAccessManager::GetOperation 2 Retrieve titles and download content (created using get())
QNetworkAccessManager::PutOperation 3 Upload content operation (created using put())
QNetworkAccessManager::PostOperation 4 Send the contents of an HTML form for processing via HTTP POST (created using POST())
QNetworkAccessManager::DeleteOperation 5 Delete content operation (created by deleteResource())
QNetworkAccessManager::CustomOperation 6 Custom operation (created using sendCustomRequest())

Its function is:

  1. Identify network operation type: Through Operation enumeration, different types of network operations can be clearly identified and distinguished, such as GET requests, POST requests, etc.
  2. Management and scheduling of network operations: QNetworkAccessManager uses the Operation enumeration to manage and schedule different network requests. Depending on the type of operation, it can perform corresponding processing logic and resource management.
  3. Error handling and retry strategies: When a network error occurs, different error handling strategies or retry strategies can be adopted based on the type of operation.
QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const

Returns the currently active network configuration.

If the network configuration returned by configuration() is of type QNetworkConfiguration:: servicennetwork, this function will return the currently active subnetwork configuration for that configuration. Otherwise return the same network configuration asconfiguration().

Use this function to return the actual network configuration currently being used by the network session.

Related to this function are two other functions:
QNetworkConfiguration QNetworkAccessManager::configuration() const and
void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config)
Set the network configuration that will be used when creating the network session to be configured.
Network configuration is used to create and open a network session before processing any requests that require network access. If the network configuration is not set explicitly through this function, the network configuration returned byQNetworkConfigurationManager::defaultConfiguration() is used.
To restore the default network configuration, set the network configuration to the value returned by QNetworkConfigurationManager::defaultConfiguration().
Setting the network configuration means that QNetworkAccessManager the instance will only use the specified one. In particular, if the default network configuration changes (for example, Wifi is available), the new configuration needs to be enabled manually.

QNetworkConfigurationManager manager; networkAccessManager->setConfiguration(manager.defaultConfiguration());

If an invalid network configuration is set, the network session will not be created. In this case, the network request will be processed anyway, but may fail. For example:

networkAccessManager→setConfiguration (QNetworkConfiguration ()); 
void QNetworkAccessManager::addStrictTransportSecurityHosts(const QVector<QHstsPolicy> &knownHosts)

Add HTTP strict transport security policy to the HSTS cache.
NOTE: Expired policies will remove known hosts from the cache if they previously existed.
Note: When processing HTTP responses, QNetworkAccessManager can also update the HSTS cache, delete or update existing policies or introduce new knownHosts. Therefore, the current implementation is server-driven and client code can provide QNetworkAccessManager with previously known or discovered policies, but this information can be overwritten by the "Strict-Transport-Security" response.
Its function is to add a host to the list of known 严格传输安全性 (Strict Transport Security, HSTS) hosts. And tells QNetworkAccessManager to only use HTTPS 与特定的主机通信,以确保通信的安全性。通过将主机添加到已知的主机列表中,浏览器将只使用 HTTPS 与这些主机通信,从而防止攻击。 这个函数在Qt 5.9` version to be used.

void QNetworkAccessManager::setCache(QAbstractNetworkCache *cache)

Sets the manager's network cache to the specified cache. The cache is used for all requests scheduled by the manager.
Use this function to set a network cache object to a class that implements additional functionality, such as saving cookie to persistent storage.
Note: QNetworkAccessManagerGet ownership of the cached object.
By default, QNetworkAccessManager no cache is set. Qt provides a simple disk cache,QNetworkDiskCache, that can be used.
corresponds to the cache() function, which returns a cache used to store data obtained from the network. .

void QNetworkAccessManager::clearAccessCache()

Refreshes the internal cache of authentication data and network connections.
This function is useful when performing automated testing.

void QNetworkAccessManager::clearConnectionCache()

Refreshes the internal cache of network connections. Compared to clearAccessCache(), authentication data is preserved.

void QNetworkAccessManager::connectToHost(const QString &hostName, quint16 port= 80)

Initiates a connection to the host specified by the hostname on port port. This function helps reduce network latency by completing the TCP handshake with the host before making an HTTP request.
Note: This function cannot report errors.

void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quint16 port= 443,const QSslConfiguration &sslConfiguration = QSslConfiguration::defaultConfiguration())

UsesslConfiguration to initiate a connection to the host specified by hostName on port port. This function helps reduce network latency by completing TCP and SSL handshakes with the host before making an HTTPS request.
Note: Pre-connected SPDY connections can be accomplished by calling setAllowedNextProtocols() on the sslConfiguration using QSslConfiguration::NextProtocolSpdy3_0 that is included in the list of allowed protocols. When using SPDY, one connection per host is sufficient, that is, calling this method multiple times per host will not result in faster network transactions.
Note: This function cannot report errors.

QNetworkCookieJar *QNetworkAccessManager::cookieJar() const

ReturnsQNetworkCookieJar, used to store cookie obtained from the network and cookie to be sent.

QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &request)

Sends a request to delete the resource identified by the requested URL.
Note: This feature is currently only available for HTTP, executing HTTP DELETE requests.
In addition, there are the following commonly used functions:
1.get(const QNetworkRequest &request) a> signal. object that is opened for reading whenever new data arrives. The object will emit the issues a request to get the contents of the target request and returns a new
Sends an HTTP GET request to the specified URL. :
QNetworkReplyreadyRead()

content and associated titles will be downloaded.
2.head(const QNetworkRequest &request):
Send an HTTP HEAD requests the specified URL. HEAD requests are similar to GET requests, but do not return a message body.
Sends a request to get the request's network headers and returns a new QNetworkReply object that will contain these headers.

This function is named after the associated HTTP request (HEAD).
3. isStrictTransportSecurityEnabled() const:
4. Returns a Boolean value, Indicates whether Strict Transport Security (HSTS) is enabled.
5. networkAccessible() const: Returns the current network accessibility status.
6. post(const QNetworkRequest &request, QIODevice *data):
Send an HTTP POST request to the specified URL and send the contents of the data device as the request body.
Send an HTTP POST request to the destination specified by request and return a new QNetworkReply object, which will contain the response sent by the server. The contents of the data device will be uploaded to the server.

The data must be open for reading and must remain valid until the finished() signal is emitted.

Note: Sending POST requests on protocols other than HTTP and HTTPS is undefined and may fail.

7.post(const QNetworkRequest &request, const QByteArray &data):
8 . Send an HTTP POST request to the specified URL and send the contents of the byte array as the request body.
9. post(const QNetworkRequest &request, QHttpMultiPart *multiPart): Send an HTTP POST request to the specified URL, and use the QHttpMultiPart object as the request body.
10. proxy() const: Returns the currently set proxy.
Returns the that will be used by requests sent using this QNetworkAccessManager object. The default value is. QNetworkProxy“QNetworkProxy::DefaultProxy”

11.proxyFactory() const: Returns the currently used proxy factory.
12.put(const QNetworkRequest &request, QIODevice *data): Send an HTTP PUT request to the specified URL and send the contents of the data device as the request body.
Uploads the contents of the data to the target request and returns a new QNetworkReply object that will be opened for the reply.

When this function is called, the data must be opened for reading and must remain valid until the finished() signal is emitted.

Whether anything is available to read from the returned object depends on the protocol. For HTTP, the server may send a small HTML page indicating that the upload was successful (or failed). Other protocols may include content in their responses.

Note: For HTTP, this request will send a PUT request, which is not allowed by most servers. Form upload mechanisms, including those for uploading files through HTML forms, all use the POST mechanism.
13.put(const QNetworkRequest &request, const QByteArray &data): Send an HTTP PUT request to Specifies the URL and sends the contents of the byte array as the request body.
14.put(const QNetworkRequest &request, QHttpMultiPart *multiPart): Send an HTTP PUT request to the specified URL, and use the QHttpMultiPart object as the request body.
15.sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = Q_NULLPTR): Sends a custom HTTP request, using the specified verb and optional data devices.
Sends a custom request to the server identified by the requested URL.

It is the user's responsibility to send valid verbs to the server according to the HTTP specification.

This method provides a way to send verbs other than the usual verbs provided via get() or post() etc., such as sending an HTTP OPTIONS command.

If the data is not empty, the contents of the data device are uploaded to the server; in this case, the data must be opened for reading and must remain valid until the finished() signal is emitted for this reply.

Note: This feature currently only works with HTTP(S).
16.sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, const QByteArray &data): Sends a custom HTTP request using the specified verb and byte array data.
17.sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QHttpMultiPart *multiPart): Send a Custom HTTP request, using specified verb and QHttpMultiPart object.
18.setCache(QAbstractNetworkCache *cache): Set the cache for network access.
19.setCookieJar(QNetworkCookieJar *cookieJar): Sets a cookie container for storing and retrieving cookie information.
20.setNetworkAccessible(NetworkAccessibility accessible): Set the accessibility status of the network.
21.setProxy(const QNetworkProxy &proxy): Set network proxy.
22.setProxyFactory(QNetworkProxyFactory *factory): Set the proxy factory for dynamically generating proxy objects.
23.setRedirectPolicy(QNetworkRequest::RedirectPolicy policy): Set the redirection policy.
24.setStrictTransportSecurityEnabled(bool enabled): Enable or disable Strict Transport Security (HSTS).
25.strictTransportSecurityHosts() const: Returns a vector containing HSTS-enabled hosts.
26.supportedSchemes() const: Returns the list of protocol schemes supported by this network access manager.

Signal

  1. authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator):

    • This signal is triggered when a network request requires authentication.
    • reply is the QNetworkReply object associated with this request.
    • authenticator is a QAuthenticator object that can be used to provide a username and password or other authentication information.

This signal is emitted whenever authentication is requested to the server before delivering the requested content. The slot connected to this signal should populate the credentials for what is in the authenticator object (which can be determined by inspecting the reply object).

QNetworkAccessManager will cache the credentials internally and send the same value when the server requires authentication again without emitting the authenticationRequired() signal. If it rejects the credentials, this signal will be emitted again.

Note: To make the request without sending credentials, you cannot call setUser() or setPassword() on the authenticator object. This will cause the finished() signal to be emitted with a QNetworkReply with the error AuthenticationRequiredError.

Note: It is not possible to connect to this signal using QueuedConnection because if the authenticator does not fill in the new information when the signal returns, the connection will fail.
2. encrypted(QNetworkReply *reply):

  • This signal is triggered when a network request is successfully encrypted.
  • reply is the QNetworkReply object associated with this request.

This signal is emitted when the SSL/TLS session successfully completes the initial handshake. At this point, no user data has been transferred. This signal can be used to perform additional checks on the certificate chain, for example, to notify users when a website's certificate has changed. The response parameters specify which network is responsible for the response. If the reply does not meet the expected criteria, the reply should be aborted by calling QNetworkReply::abort() through the slot connected to this signal. The SSL configuration in use can be checked using the QNetworkReply::sslConfiguration() method.

Internally, QNetworkAccessManager can open multiple connections to the server, allowing it to process requests in parallel. These connections can be reused, which means that the encrypted() signal will not be emitted. This means that during the lifetime of the QNetworkAccessManager, you are only guaranteed to receive the signal the first time you connect to the site.
3. finished(QNetworkReply *reply):

  • This signal is triggered when a network request is completed, whether successful or failed.
  • reply is the QNetworkReply object associated with this request.

This signal is sent when the waiting network response is completed. The reply parameter will contain a pointer to the reply just completed. This signal is emitted together with the QNetworkReply::finished() signal.
Note: Do not delete the response object in the slot connected to this signal. Use deleteLater().
4. networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible):

  • This signal is triggered when the network's accessibility status changes.
  • accessibleis the current network accessibility status.
  1. preSharedKeyAuthenticationRequired(QNetworkReply *reply, QSslPreSharedKeyAuthenticator *authenticator):
  • This signal is triggered when authentication using a pre-shared key is required.
  • reply is the QNetworkReply object associated with this request.
  • authenticator is a QSslPreSharedKeyAuthenticator object that provides authentication information for a preshared key.

This signal is emitted if the SSL/TLS handshake negotiated a PSK cipher suite and therefore requires PSK authentication. The reply object is the QNetworkReply for which such cipher suite is being negotiated.

When using PSK, the client must send a valid identity and a valid pre-shared key to the server in order for the SSL handshake to proceed. Applications can fill in the passed authenticator object as needed, providing this information in the slot connected to this signal.

NOTE: Ignoring this signal, or failing to provide the required credentials, will cause the handshake to fail and the connection to be aborted.

Note: The verifier object is owned by the responder and cannot be deleted by the application.
6. proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator):
* This signal is triggered when the proxy server requires authentication.
* proxy is the proxy server that requires authentication.
* authenticator is a QAuthenticator object that you can use to provide authentication information for the proxy.

This signal is emitted whenever a proxy requests authentication and QNetworkAccessManager cannot find valid cached credentials. The slot connected to this signal should fill in the credentials for the proxy agent in the authenticator object.

QNetworkAccessManager will cache credentials internally. The next time a proxy requests authentication, QNetworkAccessManager will automatically send the same credentials without emitting the proxyAuthenticationRequired signal again.

QNetworkAccessManager will signal again if the proxy rejects the credentials.
7. sslErrors(QNetworkReply *reply, const QList &errors):
* This signal is triggered when an error occurs in the SSL connection.
* reply is the QNetworkReply object associated with this request.
* errors is a list containing all SSL errors.

This signal is emitted if the SSL/TLS session encounters errors during setup, including certificate validation errors. The errors parameter contains a list of errors, and reply is the QNetworkReply that encountered these errors.

To indicate that the error is not fatal and the connection should continue, the QNetworkReply::ignoreSslErrors() function should be called from the slot connected to this signal. If it is not called, the SSL session will be disconnected before any data (including URLs) is exchanged.

This signal can be used to display an error message to the user indicating that security may have been compromised and to display the SSL settings. If the user decides to continue after parsing the remote certificate, the slot should call ignoreSslErrors().

Example

The following passQNetworkAccessManager is an example of downloading a local file system. main.cpp

#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QSslError>
#include <QStringList>
#include <QTimer>
#include <QUrl>
#include <QDebug>

#include <stdio.h>

class DownloadManager: public QObject
{
    
    
    Q_OBJECT
    QNetworkAccessManager manager;
    QList<QNetworkReply *> currentDownloads;

public:
    DownloadManager();
    void doDownload(const QUrl &url);
    QString saveFileName(const QUrl &url);
    bool saveToDisk(const QString &filename, QIODevice *data);

public slots:
    void execute();
    void downloadFinished(QNetworkReply *reply);
    void sslErrors(const QList<QSslError> &errors);
};

DownloadManager::DownloadManager()
{
    
    
    connect(&manager, SIGNAL(finished(QNetworkReply*)),
            SLOT(downloadFinished(QNetworkReply*)));
}

void DownloadManager::doDownload(const QUrl &url)
{
    
    
    QNetworkRequest request(url);
    // 当get完成后,触发downloadFinished(QNetworkReply*)槽函数
    QNetworkReply *reply = manager.get(request);
    
    connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(sslErrors(QList<QSslError>)));

    currentDownloads.append(reply);
}

QString DownloadManager::saveFileName(const QUrl &url)
{
    
    
    // 当存在是,后面依次追加数字
    QString path = url.path();
    QString strFileName = QFileInfo(path).fileName();
    QString strSuffix = QFileInfo(path).suffix();
    QString basename = QFileInfo(path).completeBaseName();

    if (basename.isEmpty())
        basename = "download";

    QString strSaveName = strFileName;
    if (QFile::exists(strSaveName)) {
    
    
        int i = 0;
        while (QFile::exists(basename + QString::number(i) + '.' + strSuffix))
            ++i;

        strSaveName = basename + QString::number(i) + '.' + strSuffix;
    }

    return strSaveName;
}

bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data)
{
    
    
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly)) {
    
    
        fprintf(stderr, "Could not open %s for writing: %s\n",
                qPrintable(filename),
                qPrintable(file.errorString()));
        return false;
    }

    file.write(data->readAll());
    file.close();

    return true;
}

void DownloadManager::execute()
{
    
    
    // 添加文件信息
    QStringList args;
    args << QString("file:///F:/haha/111.txt") << QString("file:///F:/haha/222.txt")
         << QString("file:///F:/haha/333.txt") << QString("file:///F:/haha/444.txt")
         << QString("file:///F:/haha/555.txt") << QString("file:///F:/haha/666.txt")
         << QString("file:///F:/haha/777.txt") << QString("file:///F:/haha/888.txt")
         << QString("file:///F:/haha/999.txt") << QString("file:///F:/haha/101010.txt");
    if (args.isEmpty()) {
    
    
        printf("null    faild    .");
        QCoreApplication::instance()->quit();
        return;
    }

    foreach (QString arg, args) {
    
    
        // 转换成url
        QUrl url = QUrl::fromEncoded(arg.toLocal8Bit());
        doDownload(url);
    }
}

void DownloadManager::sslErrors(const QList<QSslError> &sslErrors)
{
    
    
    foreach (const QSslError &error, sslErrors)
        fprintf(stderr, "SSL error: %s\n", qPrintable(error.errorString()));
}

void DownloadManager::downloadFinished(QNetworkReply *reply)
{
    
    
    QUrl url = reply->url();
    if (reply->error()) {
    
    
        fprintf(stderr, "Download of %s failed: %s\n",
                url.toEncoded().constData(),
                qPrintable(reply->errorString()));
    } else {
    
    
        // 修改保存文件名称
        QString filename = saveFileName(url);
        // 保存
        if (saveToDisk(filename, reply))
            printf("Download of %s succeeded (saved to %s)\n",
                   url.toEncoded().constData(), qPrintable(filename));
    }

    currentDownloads.removeAll(reply);
    reply->deleteLater();

    if (currentDownloads.isEmpty())
    {
    
    
        fprintf(stderr, "%s\n", "finished.");
        QCoreApplication::instance()->quit();
    }
}

int main(int argc, char **argv)
{
    
    
    QCoreApplication app(argc, argv);

    // 声明对象
    DownloadManager manager;
    // 执行下载操作
    QTimer::singleShot(0, &manager, SLOT(execute()));

    app.exec();
}

#include "main.moc"

The above example is a multi-file download manager based on the Qt network module.
By using QNetworkAccessManager, it allows users to download multiple files at the same time and save the files to disk.
Main functions:
1. Create the DownloadManager class, inherit from QObject, and inherit the manager object from QNetworkAccessManager.
2. doDownload function: accepts a QUrl object as a parameter, encapsulates it into QNetworkRequest, and then sends a GET request through the manager object.
3. saveFileName function: Generate a file name based on the path of the url, and ensure that the file name is not repeated.
4.saveToDisk function: Save the downloaded file to disk.
5.execute function: Execute the download operation, add file information to QStringList, and call the doDownload function in a loop to download multiple files at the same time.
6.sslErrors function: Handle SSL errors.
7. downloadFinished function: Process when the download is completed, determine whether an error has occurred, and perform operations such as saving the file and printing download success information.
8. Main function: Create QCoreApplication object and DownloadManager object, and implement asynchronous call and execute function through QTimer::singleShot.

Effect:
Insert image description here

in conclusion

如果上帝没有给你你想要的,那不是你值得更好,而是你不值得

Guess you like

Origin blog.csdn.net/MrHHHHHH/article/details/135001466