Qt Networking

QTcpSocket, QUdpSocket, QNetworkAccessManager — TCP/UDP communication and REST API clients.

3 min read
31690 chars

Qt Network Module

Add to your CMakeLists.txt:

find_package(Qt6 REQUIRED COMPONENTS Network)
target_link_libraries(MyApp PRIVATE Qt6::Network)

TCP Client — QTcpSocket

// tcpclient.h
#include <QObject>
#include <QTcpSocket>

class TcpClient : public QObject {
    Q_OBJECT
public:
    explicit TcpClient(QObject *parent = nullptr);
    void connectToServer(const QString &host, quint16 port);
    void sendMessage(const QString &msg);

signals:
    void messageReceived(const QString &msg);
    void connected();
    void disconnected();

private slots:
    void onConnected();
    void onReadyRead();
    void onError(QAbstractSocket::SocketError error);

private:
    QTcpSocket *m_socket;
};
// tcpclient.cpp
#include "tcpclient.h"

TcpClient::TcpClient(QObject *parent) : QObject(parent) {
    m_socket = new QTcpSocket(this);

    connect(m_socket, &QTcpSocket::connected,    this, &TcpClient::onConnected);
    connect(m_socket, &QTcpSocket::readyRead,    this, &TcpClient::onReadyRead);
    connect(m_socket, &QTcpSocket::disconnected, this, &TcpClient::disconnected);
    connect(m_socket, &QAbstractSocket::errorOccurred, this, &TcpClient::onError);
}

void TcpClient::connectToServer(const QString &host, quint16 port) {
    m_socket->connectToHost(host, port);
}

void TcpClient::sendMessage(const QString &msg) {
    if (m_socket->state() == QAbstractSocket::ConnectedState) {
        m_socket->write(msg.toUtf8());
        m_socket->flush();
    }
}

void TcpClient::onConnected() {
    qDebug() << "Connected to server";
    emit connected();
}

void TcpClient::onReadyRead() {
    QByteArray data = m_socket->readAll();
    emit messageReceived(QString::fromUtf8(data));
}

void TcpClient::onError(QAbstractSocket::SocketError error) {
    qWarning() << "Socket error:" << m_socket->errorString();
}

TCP Server — QTcpServer

#include <QTcpServer>
#include <QTcpSocket>

class EchoServer : public QObject {
    Q_OBJECT
public:
    explicit EchoServer(QObject *parent = nullptr) : QObject(parent) {
        m_server = new QTcpServer(this);
        connect(m_server, &QTcpServer::newConnection,
                this, &EchoServer::onNewConnection);
    }

    void listen(quint16 port) {
        if (!m_server->listen(QHostAddress::Any, port))
            qWarning() << "Server failed:" << m_server->errorString();
        else
            qDebug() << "Listening on port" << port;
    }

private slots:
    void onNewConnection() {
        QTcpSocket *client = m_server->nextPendingConnection();

        connect(client, &QTcpSocket::readyRead, [client]() {
            QByteArray data = client->readAll();
            qDebug() << "Received:" << data;
            client->write(data);  // echo back
        });

        connect(client, &QTcpSocket::disconnected,
                client, &QTcpSocket::deleteLater);
    }

private:
    QTcpServer *m_server;
};

UDP — QUdpSocket

UDP is stateless — ideal for sensor broadcasts and time-critical data:

#include <QUdpSocket>
#include <QHostAddress>

// --- Sender ---
QUdpSocket sender;
QByteArray payload = "TEMP:36.5;HUM:60.2";
sender.writeDatagram(payload, QHostAddress("192.168.1.255"), 5000);

// --- Receiver ---
class UdpReceiver : public QObject {
    Q_OBJECT
public:
    explicit UdpReceiver(QObject *parent = nullptr) : QObject(parent) {
        m_socket = new QUdpSocket(this);
        m_socket->bind(QHostAddress::Any, 5000);
        connect(m_socket, &QUdpSocket::readyRead, this, &UdpReceiver::onReadyRead);
    }

private slots:
    void onReadyRead() {
        while (m_socket->hasPendingDatagrams()) {
            QByteArray data;
            data.resize(m_socket->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;
            m_socket->readDatagram(data.data(), data.size(), &sender, &senderPort);
            qDebug() << "From" << sender.toString() << ":" << data;
        }
    }

private:
    QUdpSocket *m_socket;
};

HTTP / REST — QNetworkAccessManager

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>

class RestClient : public QObject {
    Q_OBJECT
public:
    explicit RestClient(QObject *parent = nullptr) : QObject(parent) {
        m_manager = new QNetworkAccessManager(this);
    }

    // GET request
    void get(const QUrl &url) {
        QNetworkRequest req(url);
        req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

        QNetworkReply *reply = m_manager->get(req);
        connect(reply, &QNetworkReply::finished, [reply, this]() {
            if (reply->error() == QNetworkReply::NoError) {
                QByteArray body = reply->readAll();
                QJsonDocument doc = QJsonDocument::fromJson(body);
                emit jsonReceived(doc.object());
            } else {
                qWarning() << "GET error:" << reply->errorString();
            }
            reply->deleteLater();
        });
    }

    // POST JSON
    void postJson(const QUrl &url, const QJsonObject &payload) {
        QNetworkRequest req(url);
        req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

        QByteArray body = QJsonDocument(payload).toJson();
        QNetworkReply *reply = m_manager->post(req, body);
        connect(reply, &QNetworkReply::finished, [reply]() {
            qDebug() << "POST response:" << reply->readAll();
            reply->deleteLater();
        });
    }

signals:
    void jsonReceived(const QJsonObject &obj);

private:
    QNetworkAccessManager *m_manager;
};

Usage:

RestClient client;
client.get(QUrl("http://192.168.1.10/api/sensors"));

QJsonObject payload;
payload["device"] = "sensor_01";
payload["value"] = 36.5;
client.postJson(QUrl("http://api.example.com/data"), payload);

Network Monitoring

#include <QNetworkInformation>

// Check connectivity
QNetworkInformation::loadBackendByFeatures(QNetworkInformation::Feature::Reachability);
auto *ni = QNetworkInformation::instance();

connect(ni, &QNetworkInformation::reachabilityChanged,
        [](QNetworkInformation::Reachability r) {
            if (r == QNetworkInformation::Reachability::Online)
                qDebug() << "Network: Online";
            else
                qDebug() << "Network: Offline";
        });

Summary

ClassUse Case
QTcpSocketTCP client — connect, send, receive
QTcpServerTCP server — accept connections
QUdpSocketUDP datagrams — broadcasts, low-latency data
QNetworkAccessManagerHTTP GET/POST/PUT — REST APIs
QNetworkReplyAsync HTTP response
QJsonDocumentParse and build JSON

Next tutorial → Multithreading with Qt