Spec-Zone.ru › Qt 5.6

Программирование сетей с Qt

Модуль сетей Qt предлагает классы, которые позволяют создавать TCP/IP-клиенты и серверы. Он предоставляет низкоуровневые классы, такие как QTcpSocket, QTcpServer и QUdpSocket, которые представляют низкоуровневые сетевые концепции, и высокоуровневые классы, такие как QNetworkRequest, QNetworkReply и QNetworkAccessManager, для выполнения сетевых операций с помощью общих протоколов. Он также предоставляет классы, такие как QNetworkConfiguration, QNetworkConfigurationManager и QNetworkSession, которые реализуют управление носителем.

Классы Qt для программирования сетей

Страница Qt Network C++ Classes содержит список классов C++ в Qt Network.

Высокоуровневые сетевые операции для HTTP и FTP

API доступа к сетям — это набор классов для выполнения общих сетевых операций. API предоставляет абстракционный слой над конкретными операциями и протоколами (например, получение и отправка данных по HTTP), и раскрывает только классы, функции и сигналы для общих или высокоуровневых концепций.

Сеть запросы представлены классом QNetworkRequest, который также действует как общий контейнер для информации, связанной с запросом, такой как любая информация в заголовке и используемое шифрование. URL-адрес, указанный при создании объекта запроса, определяет протокол, используемый для запроса. В настоящее время поддерживаются URL-адреса HTTP, FTP и локальных файлов для загрузки и скачивания.

Координация сетевых операций выполняется классом QNetworkAccessManager. После создания запроса этот класс используется для его отправки и выдачи сигналов для отчета о его ходе. Менеджер также координирует использование куки для хранения данных на клиенте, запросов аутентификации и использования прокси-серверов.

Ответы на сетевые запросы представлены классом QNetworkReply; они создаются QNetworkAccessManager при отправке запроса. Сигналы, предоставляемые QNetworkReply, могут использоваться для отслеживания каждого ответа индивидуально, или разработчики могут выбрать использование сигналов менеджера для этой цели вместо этого и отказаться от ссылок на ответы. Поскольку QNetworkReply является подклассом QIODevice, ответы могут обрабатываться синхронно или асинхронно; т.е., как блокирующие или неблокирующие операции.

Каждое приложение или библиотека может создавать один или несколько экземпляров QNetworkAccessManager для обработки сетевого общения.

Использование TCP с QTcpSocket и QTcpServer

TCP (Transmission Control Protocol) — это низкоуровневый сетевой протокол, используемый большинством интернет-протоколов, включая HTTP и FTP, для передачи данных. Это надёжный, потоковый, ориентированный на соединение транспортный протокол. Он особенно подходит для непрерывной передачи данных.

A TCP Stream

Класс QTcpSocket предоставляет интерфейс для TCP. Вы можете использовать QTcpSocket для реализации стандартных сетевых протоколов, таких как POP3, SMTP и NNTP, а также пользовательских протоколов.

Соединение TCP должно быть установлено с удалённым хостом и портом перед началом любой передачи данных. После установления соединения IP-адрес и порт узла-партнёра доступны через QTcpSocket::peerAddress() и QTcpSocket::peerPort(). В любое время узел-партнёр может закрыть соединение, и передача данных немедленно остановится.

QTcpSocket работает асинхронно и генерирует сигналы для отчётов о изменениях статуса и ошибках, как и QNetworkAccessManager. Он полагается на цикл событий для обнаружения входящих данных и автоматического сброса исходящих данных. Вы можете записать данные в сокет, используя QTcpSocket::write(), и прочитать данные, используя QTcpSocket::read(). QTcpSocket представляет два независимых потока данных: один для чтения и один для записи.

Поскольку QTcpSocket наследуется от QIODevice, вы можете использовать его с QTextStream и QDataStream. При чтении из QTcpSocket вы должны убедиться, что достаточно данных доступны, вызвав QTcpSocket::bytesAvailable() предварительно.

Если вам нужно обрабатывать входящие TCP-соединения (например, в приложении-сервере), используйте класс QTcpServer. Вызовите QTcpServer::listen() для настройки сервера и подключитесь к сигналу QTcpServer::newConnection(), который генерируется один раз для каждого подключившегося клиента. В вашем слоте вызовите QTcpServer::nextPendingConnection() для принятия подключения и используйте возвращённый QTcpSocket для общения с клиентом.

Хотя большинство его функций работают асинхронно, можно использовать QTcpSocket синхронно (т.е., блокируя). Для получения блокирующего поведения вызовите функции waitFor...() QTcpSocket; они приостанавливают вызывающую нить, пока не будет сгенерирован сигнал. Например, после вызова неблокирующей функции QTcpSocket::connectToHost() вызовите QTcpSocket::waitForConnected(), чтобы заблокировать нить, пока не будет сгенерирован сигнал connected().

Синхронные сокеты часто приводят к коду с более простым потоком управления. Основным недостатком подхода waitFor...() является то, что события не будут обрабатываться, пока функция waitFor...() блокирует. Если используется в нити GUI, это может заморозить пользовательский интерфейс приложения. По этой причине рекомендуется использовать синхронные сокеты только в не-GUI нитях. При синхронном использовании QTcpSocket не требует цикла событий.

Примеры Fortune Client и Fortune Server демонстрируют, как использовать QTcpSocket и QTcpServer для написания TCP клиент-серверных приложений. См. также пример Blocking Fortune Client для примера использования синхронного QTcpSocket в отдельной нити (без использования цикла событий), и пример Threaded Fortune Server для примера многопоточного TCP сервера с одной нитью на активного клиента.

Использование UDP с QUdpSocket

UDP (User Datagram Protocol) — это лёгкий, ненадежный, ориентированный на дейтаграммы, бессоединительный протокол. Он может использоваться, когда надёжность не важна. Например, сервер, который сообщает текущее время, может выбрать UDP. Если дейтаграмма с текущим временем потеряна, клиент может просто сделать другой запрос.

UDP Packets

Класс QUdpSocket позволяет отправлять и получать UDP-дейтаграммы. Он наследуется от QAbstractSocket, и поэтому он разделяет большую часть интерфейса QTcpSocket. Основное различие заключается в том, что QUdpSocket передает данные в виде дейтаграмм, а не в виде непрерывного потока данных. Короче говоря, дейтаграмма — это пакет данных ограниченного размера (обычно меньше 512 байт), содержащий IP-адрес и порт отправителя и получателя дейтаграммы, в дополнение к передаваемым данным.

QUdpSocket поддерживает IPv4-вещание. Вещание часто используется для реализации сетевых протоколов обнаружения, таких как поиск хоста в сети с наибольшим свободным объёмом жёсткого диска. Один хост транслирует дейтаграмму в сеть, которую получают все другие хосты. Каждый хост, который получает запрос, затем отправляет ответ отправителю со своим текущим объёмом свободного места на диске. Отправитель ждёт, пока не получит ответы от всех хостов, и затем может выбрать сервер с наибольшим объёмом свободного места для хранения данных. Чтобы транслировать дейтаграмму, просто отправьте её на специальный адрес QHostAddress::Broadcast (255.255.255.255) или на адрес вещания вашей локальной сети.

QUdpSocket::bind() готовит сокет к приему входящих дейтаграмм, так же, как QTcpServer::listen() для TCP-серверов. Всякий раз, когда одна или несколько дейтаграмм прибывают, QUdpSocket излучает сигнал readyRead(). Вызовите QUdpSocket::readDatagram() для чтения дейтаграммы.

Примеры Broadcast Sender и Broadcast Receiver демонстрируют, как написать UDP-отправителя и UDP-получателя с использованием Qt.

QUdpSocket также поддерживает мультивещание. Примеры Multicast Sender и Multicast Receiver показывают, как использовать UDP-клиенты мультивещания.

Разрешение имён хостов с помощью QHostInfo

Перед установлением сетевого соединения QTcpSocket и QUdpSocket выполняют поиск имени, переводя имя хоста, к которому вы подключаетесь, в IP-адрес. Обычно эта операция выполняется с использованием протокола DNS (Domain Name Service).

QHostInfo предоставляет статическую функцию, которая позволяет вам выполнить такой поиск самостоятельно. Вызвав QHostInfo::lookupHost() с именем хоста, указателем QObject и сигнатурой слота, QHostInfo выполнит поиск имени и вызовет указанный слот, когда результаты будут готовы. Фактический поиск выполняется в отдельной нити, используя собственные методы операционной системы для выполнения поиска имён.

QHostInfo также предоставляет статическую функцию QHostInfo::fromName(), которая принимает имя хоста в качестве аргумента и возвращает результаты. В этом случае поиск имени выполняется в той же нити, что и вызывающая сторона. Эта перегрузка полезна для приложений, не использующих GUI, или для выполнения поиска имён в отдельной нити, не использующей GUI. (Вызов этой функции в нити GUI может привести к зависанию вашего пользовательского интерфейса, пока функция блокируется, выполняя поиск.)

Поддержка сетевых прокси-серверов

Сеть взаимодействие с Qt может выполняться через прокси, которые направляют или фильтруют сетевой трафик между локальными и удаленными подключениями.

Индивидуальные прокси представлены классом QNetworkProxy, который используется для описания и настройки подключения к прокси. Поддерживаются типы прокси, работающие на разных уровнях сетевого взаимодействия, при этом поддержка SOCKS 5 позволяет проксировать сетевой трафик на низком уровне, а HTTP и FTP проксирование работает на уровне протокола. Дополнительную информацию см. в QNetworkProxy::ProxyType.

Проксирование может быть включено на основе каждого сокета или для всех сетевых взаимодействий в приложении. Новый сокет может быть настроен для использования прокси путем вызова функции QAbstractSocket::setProxy() перед его подключением. Включение проксирования для всех последующих подключений сокетов по всему приложению может быть выполнено с помощью функции QNetworkProxy::setApplicationProxy().

Прокси-фабрики используются для создания политик использования прокси. QNetworkProxyFactory предоставляет прокси на основе запросов для конкретных типов прокси. Сами запросы закодированы в объектах QNetworkProxyQuery, которые позволяют выбирать прокси на основе ключевых критериев, таких как назначение прокси (TCP, UDP, TCP-сервер, запрос URL), локальный порт, удаленный хост и порт, а также используемый протокол (HTTP, FTP и т. д.).

QNetworkProxyFactory::proxyForQuery() используется для непосредственного запроса фабрики. Политику проксирования по всему приложению можно реализовать, передав фабрику в QNetworkProxyFactory::setApplicationProxyFactory(), а пользовательскую политику проксирования можно создать, создав подкласс QNetworkProxyFactory; подробности см. в документации класса.

Поддержка управления каналом

Управление каналом контролирует состояние подключения устройства таким образом, что приложение может запускать или останавливать сетевые интерфейсы и прозрачно перемещаться между точками доступа.

Класс QNetworkConfigurationManager управляет списком сетевых конфигураций, известных устройству. Сетевая конфигурация описывает набор параметров, используемых для запуска сетевого интерфейса, и представлена классом QNetworkConfiguration.

Сетевой интерфейс запускается путем открытия QNetworkSession на основе заданной сетевой конфигурации. В большинстве случаев предпочтительно создание сетевого сеанса на основе платформенной стандартной сетевой конфигурации. Стандартная сетевая конфигурация возвращается функцией QNetworkConfigurationManager::defaultConfiguration().

На некоторых платформах требуется, чтобы приложение открыло сетевой сеанс перед выполнением любых сетевых операций. Это можно проверить по наличию флага QNetworkConfigurationManager::NetworkSessionRequired в значении, возвращаемом функцией QNetworkConfigurationManager::capabilities().

См. также Управление каналом.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.6/qtnetwork-programming.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API