Auf dieser Seite

Netzwerkprogrammierung mit Qt

Das Modul „ Qt Network “ bietet Klassen, mit denen Sie TCP/IP-Clients und -Server schreiben können. Es enthält Klassen auf niedrigerer Ebene wie „ QTcpSocket “, „ QTcpServer “ und „ QUdpSocket “, die grundlegende Netzwerkkonzepte abbilden, sowie Klassen auf höherer Ebene wie „ QNetworkRequest “, „ QNetworkReply “ und „ QNetworkAccessManager “ zur Durchführung von Netzwerkoperationen unter Verwendung gängiger Protokolle.

Qt Network Außerdem wird eine API für Transport Layer Security (TLS) sowie Sicherheitsfunktionen bereitgestellt, die ein natives TLS-Backend, das OpenSSL-Toolkit oder ein beliebiges geeignetes TLS-Plugin nutzen. Weitere Informationen finden Sie unter „Secure Sockets Layer (SSL)-Klassen “.

Qt-Klassen für die Netzwerkprogrammierung

Die Qt Network C++ Classes Seite enthält eine Liste der C++-Klassen in „ Qt Network “.

Netzwerkoperationen auf hoher Ebene für HTTP

Die Netzwerkzugriffs-API ist eine Sammlung von Klassen zur Durchführung gängiger Netzwerkoperationen. Die API stellt eine Abstraktionsschicht über die spezifischen Operationen und verwendeten Protokolle dar (z. B. das Abrufen und Senden von Daten über HTTP) und stellt nur Klassen, Funktionen und Signale für allgemeine oder übergeordnete Konzepte bereit.

Netzwerkanfragen werden durch die Klasse „ QNetworkRequest “ dargestellt, die gleichzeitig als allgemeiner Container für Informationen dient, die mit einer Anfrage verbunden sind, wie z. B. Header-Informationen und die verwendete Verschlüsselung. Die beim Erstellen eines Anfrageobjekts angegebene URL bestimmt das für die Anfrage verwendete Protokoll. Derzeit werden HTTP und lokale Datei-URLs für das Hoch- und Herunterladen unterstützt.

Die Koordination der Netzwerkoperationen erfolgt durch die Klasse „ QNetworkAccessManager “. Sobald eine Anfrage erstellt wurde, wird diese Klasse verwendet, um sie zu versenden und Signale auszugeben, die über ihren Fortschritt berichten. Der Manager koordiniert außerdem die Verwendung von „ cookies “ zum Speichern von Daten auf dem Client, Authentifizierungsanfragen sowie die Nutzung von Proxys.

Antworten auf Netzwerkanfragen werden durch die Klasse „ QNetworkReply “ repräsentiert; diese werden von „ QNetworkAccessManager “ erstellt, wenn eine Anfrage versendet wird. Die von „ QNetworkReply “ bereitgestellten Signale können verwendet werden, um jede Antwort einzeln zu überwachen, oder Entwickler können stattdessen die Signale des Managers für diesen Zweck nutzen und Verweise auf Antworten verwerfen. Da „ QNetworkReply “ eine Unterklasse von „ QIODevice “ ist, können Antworten synchron oder asynchron verarbeitet werden, d. h. als blockierende oder nicht blockierende Operationen.

Jede Anwendung oder Bibliothek kann eine oder mehrere Instanzen von ` QNetworkAccessManager ` erstellen, um die Netzwerkkommunikation abzuwickeln.

Verwendung von TCP mit `QTcpSocket` und `QTcpServer`

TCP (Transmission Control Protocol) ist ein Low-Level-Netzwerkprotokoll, das von den meisten Internetprotokollen, darunter HTTP und FTP, zur Datenübertragung verwendet wird. Es handelt sich um ein zuverlässiges, strömungsorientiertes und verbindungsorientiertes Transportprotokoll. Es eignet sich besonders gut für die kontinuierliche Datenübertragung.

Ein TCP-Stream

Die Klasse „ QTcpSocket “ stellt eine Schnittstelle für TCP bereit. Mit „ QTcpSocket “ können Sie sowohl Standard-Netzwerkprotokolle wie POP3, SMTP und NNTP als auch benutzerdefinierte Protokolle implementieren.

Bevor eine Datenübertragung beginnen kann, muss eine TCP-Verbindung zu einem entfernten Host und Port aufgebaut werden. Sobald die Verbindung hergestellt ist, sind die IP-Adresse und der Port des Gegenüber über ` QTcpSocket::peerAddress()` und ` QTcpSocket::peerPort()` abrufbar. Das Gegenüber kann die Verbindung jederzeit schließen, woraufhin die Datenübertragung sofort beendet wird.

QTcpSocket arbeitet asynchron und gibt Signale aus, um Statusänderungen und Fehler zu melden, genau wie QNetworkAccessManager. Es nutzt die Ereignisschleife, um eingehende Daten zu erkennen und ausgehende Daten automatisch zu übertragen. Sie können Daten mit QTcpSocket::write() in den Socket schreiben und mit QTcpSocket::read() lesen. QTcpSocket stellt zwei unabhängige Datenströme dar: einen zum Lesen und einen zum Schreiben.

Da „ QTcpSocket “ von „ QIODevice “ erbt, können Sie es mit „ QTextStream “ und „ QDataStream “ verwenden. Beim Lesen aus einem „ QTcpSocket “ müssen Sie sicherstellen, dass genügend Daten verfügbar sind, indem Sie zuvor „ QTcpSocket::bytesAvailable()“ aufrufen.

Wenn Sie eingehende TCP-Verbindungen verarbeiten müssen (z. B. in einer Serveranwendung), verwenden Sie die Klasse „ QTcpServer “. Rufen Sie „ QTcpServer::listen()“ auf, um den Server einzurichten, und verbinden Sie sich mit dem Signal „ QTcpServer::newConnection()“, das bei jeder Verbindung eines Clients einmal ausgelöst wird. Rufen Sie in Ihrem Slot „ QTcpServer::nextPendingConnection()“ auf, um die Verbindung anzunehmen, und verwenden Sie den zurückgegebenen „ QTcpSocket “, um mit dem Client zu kommunizieren.

Obwohl die meisten Funktionen asynchron arbeiten, ist es möglich, „ QTcpSocket “ synchron (d. h. blockierend) zu verwenden. Um ein blockierendes Verhalten zu erzielen, rufen Sie die `waitFor...()`-Funktionen von ` QTcpSocket` auf; diese halten den aufrufenden Thread an, bis ein Signal ausgesendet wurde. Rufen Sie beispielsweise nach dem Aufruf der nicht blockierenden Funktion ` QTcpSocket::connectToHost()` die Funktion ` QTcpSocket::waitForConnected()` auf, um den Thread zu blockieren, bis das Signal ` connected()` ausgesendet wurde.

Synchrone Sockets führen oft zu Code mit einem einfacheren Kontrollfluss. Der Hauptnachteil des „waitFor...()“-Ansatzes besteht darin, dass Ereignisse nicht verarbeitet werden, solange eine „waitFor...()“-Funktion blockiert. Bei Verwendung im GUI-Thread kann dies dazu führen, dass die Benutzeroberfläche der Anwendung einfriert. Aus diesem Grund empfehlen wir, synchrone Sockets nur in Nicht-GUI-Threads zu verwenden. Bei synchroner Verwendung benötigt „ QTcpSocket “ keine Ereignisschleife.

Die Beispiele „Fortune Client“ und „Fortune Server“ zeigen, wie man mit „ QTcpSocket “ und „ QTcpServer “ TCP-Client-Server-Anwendungen schreibt. Siehe auch „Blocking Fortune Client“ für ein Beispiel zur Verwendung eines synchronen „ QTcpSocket “ in einem separaten Thread (ohne Verwendung einer Ereignisschleife) sowie „Threaded Fortune Server“ für ein Beispiel eines multithreaded TCP-Servers mit einem Thread pro aktivem Client.

Verwendung von UDP mit QUdpSocket

UDP (User Datagram Protocol) ist ein schlankes, unzuverlässiges, datagrammorientiertes und verbindungsloses Protokoll. Es kann verwendet werden, wenn Zuverlässigkeit keine Rolle spielt. Beispielsweise könnte ein Server, der die Uhrzeit meldet, UDP wählen. Wenn ein Datagramm mit der Uhrzeit verloren geht, kann der Client einfach eine neue Anfrage stellen.

UDP-Pakete

Die Klasse „ QUdpSocket “ ermöglicht das Senden und Empfangen von UDP-Datagrammen. Sie erbt von „ QAbstractSocket “ und teilt daher den Großteil der Schnittstelle von „ QTcpSocket “. Der Hauptunterschied besteht darin, dass „ QUdpSocket “ Daten als Datagramme statt als kontinuierlichen Datenstrom überträgt. Kurz gesagt ist ein Datagramm ein Datenpaket begrenzter Größe (normalerweise kleiner als 512 Byte), das neben den zu übertragenden Daten auch die IP-Adresse und den Port des Absenders und des Empfängers des Datagramms enthält.

QUdpSocket unterstützt IPv4-Broadcasting. Broadcasting wird häufig zur Implementierung von Netzwerk-Erkennungsprotokollen verwendet, beispielsweise um herauszufinden, welcher Host im Netzwerk über den meisten freien Festplattenspeicher verfügt. Ein Host sendet ein Datagramm per Broadcasting an das Netzwerk, das alle anderen Hosts empfangen. Jeder Host, der eine Anfrage erhält, sendet daraufhin eine Antwort mit seiner aktuellen freien Festplattenspeichermenge an den Absender zurück. Der Absender wartet, bis er Antworten von allen Hosts erhalten hat, und kann dann den Server mit dem meisten freien Speicherplatz zum Speichern der Daten auswählen. Um ein Datagramm per Broadcast zu versenden, senden Sie es einfach an die spezielle Adresse QHostAddress::Broadcast (255.255.255.255) oder an die Broadcast-Adresse Ihres lokalen Netzwerks.

QUdpSocket::bind() bereitet den Socket auf die Annahme eingehender Datagramme vor, ähnlich wie „ QTcpServer::listen()“ bei TCP-Servern. Sobald ein oder mehrere Datagramme eintreffen, sendet „ QUdpSocket “ das Signal „ readyRead()“ aus. Rufen Sie „ QUdpSocket::readDatagram()“ auf, um das Datagramm zu lesen.

Die Beispiele „Broadcast Sender“ und „Broadcast Receiver“ zeigen, wie man mit Qt einen UDP-Sender und einen UDP-Empfänger schreibt.

QUdpSocket unterstützt zudem Multicasting. Die Beispiele „Multicast Sender“ und „Multicast Receiver“ zeigen, wie man UDP-Multicast-Clients schreibt.

Auflösen von Hostnamen mit QHostInfo

Vor dem Aufbau einer Netzwerkverbindung führen „ QTcpSocket “ und „ QUdpSocket “ eine Namensauflösung durch und wandeln den Hostnamen, mit dem Sie eine Verbindung herstellen möchten, in eine IP-Adresse um. Dieser Vorgang erfolgt in der Regel mithilfe des DNS-Protokolls (Domain Name Service).

QHostInfo bietet eine statische Funktion, mit der Sie eine solche Abfrage selbst durchführen können. Durch den Aufruf von ` QHostInfo::lookupHost()` mit einem Hostnamen, einem ` QObject `-Zeiger und einer Slot-Signatur führt ` QHostInfo ` die Namensabfrage durch und ruft den angegebenen Slot auf, sobald die Ergebnisse vorliegen. Die eigentliche Abfrage erfolgt in einem separaten Thread unter Verwendung der betriebssystemeigenen Methoden zur Durchführung von Namensabfragen.

QHostInfo bietet außerdem eine statische Funktion namens „ QHostInfo::fromName()“, die den Hostnamen als Argument entgegennimmt und die Ergebnisse zurückgibt. In diesem Fall erfolgt die Namenssuche im selben Thread wie der Aufrufer. Diese Überladung ist nützlich für Nicht-GUI-Anwendungen oder für die Durchführung von Namenssuchen in einem separaten, nicht zur GUI gehörenden Thread. (Der Aufruf dieser Funktion in einem GUI-Thread kann dazu führen, dass Ihre Benutzeroberfläche einfriert, während die Funktion bei der Durchführung der Suche blockiert ist.)

Unterstützung für Netzwerk-Proxys

Die Netzwerkkommunikation mit Qt kann über Proxys erfolgen, die den Netzwerkverkehr zwischen lokalen und entfernten Verbindungen leiten oder filtern.

Einzelne Proxys werden durch die Klasse „ QNetworkProxy “ repräsentiert, die zur Beschreibung und Konfiguration der Verbindung zu einem Proxy dient. Es werden Proxy-Typen unterstützt, die auf verschiedenen Ebenen der Netzwerkkommunikation arbeiten: SOCKS 5 ermöglicht die Proxying-Verarbeitung des Netzwerkverkehrs auf niedriger Ebene, während HTTP- und FTP-Proxying auf Protokollebene erfolgen. Weitere Informationen finden Sie unter QNetworkProxy::ProxyType.

Die Proxy-Nutzung kann entweder für einzelne Sockets oder für die gesamte Netzwerkkommunikation einer Anwendung aktiviert werden. Ein neu geöffneter Socket kann so konfiguriert werden, dass er einen Proxy verwendet, indem vor dem Verbindungsaufbau die Funktion ` QAbstractSocket::setProxy()` aufgerufen wird. Die anwendungsweite Proxy-Nutzung kann für alle nachfolgenden Socket-Verbindungen durch den Aufruf der Funktion ` QNetworkProxy::setApplicationProxy()` aktiviert werden.

Proxy-Fabriken werden verwendet, um Richtlinien für die Proxy-Nutzung zu erstellen. ` QNetworkProxyFactory ` stellt Proxys auf der Grundlage von Abfragen nach bestimmten Proxy-Typen bereit. Die Abfragen selbst sind in ` QNetworkProxyQuery `-Objekten kodiert, die die Auswahl von Proxys anhand von Schlüsselkriterien ermöglichen, wie beispielsweise dem Zweck des Proxys (TCP, UDP, TCP-Server, URL-Anfrage), dem lokalen Port, dem Remote-Host und -Port sowie dem verwendeten Protokoll (HTTP, FTP usw.).

QNetworkProxyFactory::proxyForQuery() dient zur direkten Abfrage der Factory. Eine anwendungsweite Richtlinie für die Proxy-Nutzung lässt sich durch die Übergabe einer Factory an ` QNetworkProxyFactory::setApplicationProxyFactory()` implementieren, und eine benutzerdefinierte Proxy-Richtlinie kann durch die Erstellung einer Unterklasse von ` QNetworkProxyFactory` erstellt werden; Einzelheiten finden Sie in der Klassendokumentation.

© 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.