QT 4: программирование GUI на С++
Шрифт:
Функция getFile проверяет ошибочные ситуации так же, как рассмотренная ранее функция FtpGet::getFile, и использует тот же подход при задании имени локального файла. При загрузке файлов с веб-сайта не требуется
Запросы HTTP ставятся в очередь и обрабатываются асинхронно в цикле обработки событий Qt. На завершение выполнения запросов указывает сигнал done(bool) объекта QHttp, который мы подсоединили к слоту httpDone(bool) в конструкторе.
После выполнения запросов HTTP мы файл закрываем, уведомляя пользователя о возникновении ошибки.
Функция main очень похожа на такую же функцию в примере ftpget:
Класс QHttp содержит много операций, включая setHost, get, post и head. Если для входа на сайт необходимо выполнить аутентификацию пользователя, setUser может использоваться для установки имени пользователя и пароля. QHttp может использовать сокет, указанный программистом, а не свой собственный внутренний QTcpSocket. Это делает возможным применение безопасного сокета QtSslSocket (который предоставляется компонентом Qt Solution компании «Trolltech») для работы с HTTP через SSL.
Мы можем применять функцию post для пересылки пар «имя = значение» в сценарий CGI:
Мы можем передавать данные в виде 8-битовой строки либо передавать открытое устройство QIODevice,
например QFile. Для обеспечения большего контроля мы можем использовать функцию request, которая принимает произвольные заголовок и данные HTTP. Например:QHttp генерирует сигнал requestStarted(int) в начале выполнения команды и сигнал requestFinished(int, bool) после завершения выполнения команды. Параметр типа int является числом, которое идентифицирует запрос. Если мы собираемся отслеживать результаты выполнения отдельных запросов, мы можем сохранять эти идентификаторы при постановке запросов в очередь. Отслеживание идентификаторов обеспечивает более оперативную обратную связь с пользователем.
В большинстве приложений нас интересует результат исполнения всей последовательности команд. Это легко достигается путем подсоединения сигнала done(bool), который генерируется всякий раз, когда очередь запросов становится пустой.
При возникновении ошибки очередь запросов автоматически очищается. Но если мы после возникновения ошибки зададим новые запросы с использованием того же объекта QHttp, они будут поставлены в очередь и затем выполнены в обычном порядке.
Как и QFtp, класс QHttp содержит сигнал readyRead, а также функции read и readAll, которые мы можем использовать вместо указания устройства ввода—вывода.
Написание клиент—серверных приложений на базе TCP
Классы QTcpSocket и QTcpServer могут использоваться для реализации клиентов и серверов TCP. TCP — это транспортный протокол, который составляет основу большинства прикладных протоколов сети Интернет, включая FTP и HTTP, и который может также использоваться для создания пользовательских протоколов.
TCP является потокоориентированным протоколом. Для приложений данные представляются в виде большого потока данных, очень напоминающего большой однородный файл. Протоколы высокого уровня, построенные на основе TCP, являются либо строкоориентированными, либо блокоориентированными:
• строкоориентированные протоколы передают текстовые данные построчно, завершая каждую строку символом перехода на новую строку;
• блокоориентированные протоколы передают данные в виде двоичных блоков. Каждый блок имеет в начале поле, где указан его размер, и затем идут байты данных.
Класс QTcpSocket наследует QIODevice через класс QAbstractSocket, и поэтому чтение с него или запись на него могут производиться с применением средств класса QDataStream или QTextStream. Одно существенное отличие чтения данных из сети по сравнению с чтением обычного файла заключается в том, что мы должны быть уверены в получении достаточного количества данных от партнерского узла (peer) перед использованием оператора >>. В противном случае результат может быть непредсказуемым.