Spec-Zone.ru › Qt 5.11

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

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

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

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

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

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

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

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

Ответы на сетевые запросы представлены классом 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 с помощью 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.11/qtnetwork-programming.html

Spec-Zone.ru

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