Cliente HTTP

Demuestra un cliente HTTP simple.

Este ejemplo demuestra cómo un cliente HTTP simple puede obtener archivos de hosts remotos.

El usuario introduce la URL, el nombre del archivo y la ubicación de descarga en la ventana principal. La clase QNetworkAccessManager utiliza esta información para descargar el archivo

El trabajo principal de este ejemplo se realiza en la clase HttpWindow. Por tanto, nos centraremos en ella.

QNetworkRequest networkRequest(url);
networkRequest.setTcpKeepAliveIdleTimeBeforeProbes(20s);
networkRequest.setTcpKeepAliveIntervalBetweenProbes(2s);
networkRequest.setTcpKeepAliveProbeCount(5);

Desde Qt 6.11, es posible especificar explícitamente los parámetros TCP keepalive para QNetworkRequest. En el fragmento anterior, estamos sobreescribiendo los valores por defecto utilizados por QNetworkAccessManager para seguir una estrategia más agresiva. Esto puede ser útil, por ejemplo, en la detección temprana de cuelgues de red causados por cambios de red en Linux. En este ejemplo concreto, la conexión se cerrará tras treinta segundos de inactividad.

reply.reset(qnam.get(networkRequest));

Usando QNetworkAccessManager, comenzamos la descarga de un recurso tal y como apunta url. Si no estás familiarizado con ella o con la función utilizada, QNetworkAccessManager::get(), o simplemente quieres profundizar en ella, echa un vistazo a su documentación y a la documentación de QNetworkReply y QNetworkRequest.

    connect(reply.get(), &QNetworkReply::finished, this, &HttpWindow::httpFinished);
    connect(reply.get(), &QIODevice::readyRead, this, &HttpWindow::httpReadyRead);
#if QT_CONFIG(ssl)
    connect(reply.get(), &QNetworkReply::sslErrors, this, &HttpWindow::sslErrors);
#endif

Arriba, conectamos algunas de las señales de la respuesta a las ranuras de la clase. Estas ranuras se encargarán tanto de los datos entrantes como de finalizar la descarga/manejar los errores.

connect(reply.get(), &QIODevice::readyRead, this, &HttpWindow::httpReadyRead);

En cuanto al manejo de los datos entrantes, como no sabemos el tamaño máximo de descarga de cualquier entrada potencial y no queremos agotar la memoria de cualquier ordenador que pueda ejecutar el programa de ejemplo, manejamos los datos entrantes en QNetworkReply::readyRead() en lugar de en QNetworkReply::finished().

void HttpWindow::httpReadyRead()
{
    // This slot gets called every time the QNetworkReply has new data.
    // We read all of its new data and write it into the file.
    // That way we use less RAM than when reading it at the finished()
    // signal of the QNetworkReply
    if (file)
        file->write(reply->readAll());
}

A continuación, escribimos los datos en el archivo a medida que llegan. Es menos cómodo, ¡pero la aplicación consumirá menos memoria en su pico!

connect(reply.get(), &QNetworkReply::sslErrors, this, &HttpWindow::sslErrors);

Con la señal QNetworkReply::sslErrors() también podemos manejar errores que pueden ocurrir durante el handshake TLS cuando nos conectamos a sitios web seguros (es decir, HTTPS).

void HttpWindow::sslErrors(const QList<QSslError> &errors)
{
    QString errorString;
    for (const QSslError &error : errors) {
        if (!errorString.isEmpty())
            errorString += '\n';
        errorString += error.errorString();
    }

    if (QMessageBox::warning(this, tr("TLS Errors"),
                             tr("One or more TLS errors has occurred:\n%1").arg(errorString),
                             QMessageBox::Ignore | QMessageBox::Abort)
        == QMessageBox::Ignore) {
        reply->ignoreSslErrors();
    }
}

En este ejemplo, mostramos un diálogo al usuario para que pueda elegir si ignorar o no los errores.

QNetworkReply::NetworkError error = reply->error();
const QString &errorString = reply->errorString();
if (error != QNetworkReply::NoError) {
    QFile::remove(fi.absoluteFilePath());
    // For "request aborted" we handle the label and button in cancelDownload()
    if (!httpRequestAborted) {
        statusLabel->setText(tr("Download failed:\n%1.").arg(errorString));
        downloadButton->setEnabled(true);
    }
    return;
}

Si se produce un error, QNetworkReply emitirá la señal QNetworkReply::errorOccurred(), seguida de la señal QNetworkReply::finished(). En este ejemplo, sólo nos conectamos a esta última. Manejamos cualquier error(es) potencial(es) en la ranura respectiva borrando el archivo al que estábamos escribiendo, y mostramos el error con nuestra etiqueta de estado.

connect(&qnam, &QNetworkAccessManager::authenticationRequired,
        this, &HttpWindow::slotAuthenticationRequired);

Si te conectas a un sitio web que utiliza autenticación HTTP, suponiendo que no hayas proporcionado las credenciales que se deben utilizar de antemano, puedes manejar las credenciales faltantes cuando el sitio web lo solicite. Con QNetworkAccessManager, hacemos esto en una ranura conectada a la señal QNetworkAccessManager::authenticationRequired(). Hacemos esta conexión una vez, en el constructor.

void HttpWindow::slotAuthenticationRequired(QNetworkReply *, QAuthenticator *authenticator)
{
    QDialog authenticationDialog;
    Ui::Dialog ui;
    ui.setupUi(&authenticationDialog);
    authenticationDialog.adjustSize();
    ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm(), url.host()));

    // Did the URL have information? Fill the UI.
    // This is only relevant if the URL-supplied credentials were wrong
    ui.userEdit->setText(url.userName());
    ui.passwordEdit->setText(url.password());

    if (authenticationDialog.exec() == QDialog::Accepted) {
        authenticator->setUser(ui.userEdit->text());
        authenticator->setPassword(ui.passwordEdit->text());
    }
}

En este ejemplo, mostramos un diálogo donde el usuario puede introducir un nombre de usuario y una contraseña, o cancelar. La cancelación hace que la solicitud falle.

Proyecto de ejemplo @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.