1. Темы лекции: Работа с сетью в Qt.
Практическое задание: Клиент-серверное приложение.
Тренер: Игорь Шкулипа, к.т.н.
С++ Библиотеки STL и Qt. Занятие 7
2. http://www.slideshare.net/IgorShkulipa 2
Протокол FTP
FTP (File Transfer Protocol, протокол передачи файлов) — наиболее
известный из старых протоколов и являющийся одной из первых сетевых
служб. Целью создания этого протокола было предоставление
пользователям доступа к файлам на удаленном компьютере.
FTP отличается от других протоколов тем, что он использует два TCP
соединения для передачи файла.
• Управляющее соединение устанавливается как обычное соединение
клиент-сервер. Сервер осуществляет пассивное открытие на заранее
известный порт FTP (21) и ожидает запроса на соединение от клиента.
Клиент осуществляет активное открытие на TCP порт 21, чтобы
установить управляющее соединение. Управляющее соединение
существует все время, пока клиент общается с сервером. Это
соединение используется для передачи команд от клиента к серверу и
для передачи откликов от сервера. Тип IP сервиса для управляющего
соединения устанавливается для получения "минимальной
задержки", так как команды обычно вводятся пользователем.
• Соединение данных открывается каждый раз, когда осуществляется
передача файла между клиентом и сервером. Тип сервиса IP для
соединения данных должен быть "максимальная пропускная
способность", так как это соединение используется для передачи
файлов.
4. http://www.slideshare.net/IgorShkulipa 4
Команды FTP
Команды и отклики передаются по управляющему соединению между
клиентом и сервером в формате ASCII. В конце каждой строки команды
или отклика присутствует пара CR, LF.
Команда Описание
ABOR прервать предыдущую команду FTP и любую
передачу данных
LIST список файлов список файлов или директорий
PASS пароль пароль на сервере
PORT
n1,n2,n3,n4,n5,n6
IP адрес клиента (n1.n2.n3.n4) и порт (n5 x 256 + n6)
QUIT закрыть соединение на сервере
RETR имя файла получить (get) файл
STOR имя файла положить (put) файл
SYST сервер возвращает тип системы
TYPE тип указать тип файла: A для ASCII, I для двоичного
USER имя имя пользователя на сервере
5. http://www.slideshare.net/IgorShkulipa 5
Отклики FTP
Отклики состоят из 3-циферных значений в формате ASCII, и необязательных
сообщений, которые следуют за числами. Подобное представление откликов
объясняется тем, что программному обеспечению необходимо посмотреть только
цифровые значения, чтобы понять, что ответил процесс, а дополнительную
строку может прочитать человек.
Отклик Описание
1yz Положительный предварительный отклик. Действие началось, однако необходимо
дождаться еще одного отклика перед отправкой следующей команды.
2yz Положительный отклик о завершении. Может быть отправлена новая команда.
3yz Положительный промежуточный отклик. Команда принята, однако необходимо отправить
еще одну команду.
4yz Временный отрицательный отклик о завершении. Требуемое действие не произошло,
однако ошибка временная, поэтому команду необходимо повторить позже.
5yz Постоянный отрицательный отклик о завершении. Команда не была воспринята и
повторять ее не стоит.
x0z Синтаксическая ошибка.
x1z Информация.
x2z Соединения. Отклики имеют отношение либо к управляющему, либо к соединению данных.
x3z Аутентификация и бюджет. Отклик имеет отношение к логированию или командам,
связанным с бюджетом.
x4z Не определено.
x5z Состояние файловой системы.
6. http://www.slideshare.net/IgorShkulipa 6
Команды доступа к файлам
Протокол имеет целый ряд команд, с помощью которых можно управлять
удаленным компьютером для передачи данных:
• get — скопировать файл с удаленного сервера;
• put — копировать файл на удаленный сервер;
• rmdir — удалить каталог на удаленном сервере;
• mkdir — создать каталог на удаленном сервере;
• cd — открыть каталог на удаленном сервере;
• rename — переименовать файл или каталог на удаленном
сервере;
• close — закрыть соединение с удаленным сервером.
7. http://www.slideshare.net/IgorShkulipa 7
FTP в Qt
Класс QFtp реализует сторону клиента FTP-протокола и содержит в себе
методы для наиболее часто используемых операций с FTP.
Названия этих методов соответствуют названиям FTP-команд, например: get()
соответствует команде get, a put () — команде put и т. д.
Также класс QFtp предоставляет возможность исполнения любых FTP-команд.
Для этого в метод rawCommand() нужно передать строку, содержащую
нужную команду.
Например:
ftp.rawCommand("MKDIR MyDir");
Класс QFtp содержит методы для осуществления соединения с FTP-сервером
connectToHost(), login() и т.д.
QFile file("index.txt");
QFtp ftp;
if (file.open(QIODevice::WriteOnly)) {
ftp.connectToHost("ftp.microsoft.com");
ftp.login();
ftp.cd("Softlib");
ftp.get("index.txt", &file);
ftp.close();
file.close();
}
8. http://www.slideshare.net/IgorShkulipa 8
Протокол HTTP
HTTP (HyperText Transfer Protocol, протокол передачи гипертекста) – это
протокол прикладного уровня, разработанный для обмена
гипертекстовой информацией в Internet.
HTTP предоставляет набор методов для указания целей запроса,
отправляемого серверу. Эти методы основаны на дисциплине ссылок,
где для указания ресурса, к которому должен быть применен данный
метод, используется универсальный идентификатор ресурсов
(Universal Resource Identifier, URI) в виде местонахождения ресурса
(Universal Resource Locator, URL) или в виде его универсального
имени (Universal Resource Name, URN).
9. http://www.slideshare.net/IgorShkulipa 9
Протокол HTTP
HTTP используется для коммуникаций между различными пользовательскими
программами и программами-шлюзами, предоставляющими доступ к
существующим Internet-протоколам.
Сообщения по сети при использовании протокола HTTP передаются в формате,
схожем с форматом почтового сообщения Internet (RFC-822) или с
форматом сообщений MIME (Multiperposal Internet Mail Exchange).
Протокол реализует принцип запрос/ответ. Клиент инициирует взаимодействие
сервером и посылает запрос, содержащий:
• метод доступа;
• адрес URI;
• версию протокола;
• сообщение с информацией о типе передаваемых данных, информацией
о клиенте, пославшем запрос, и, возможно, с телом сообщения.
Ответ сервера содержит:
• строку состояния, в которую входит версия протокола и код возврата
(успех или ошибка);
• сообщение, в которое входит информация сервера, метаинформация
(т.е. информация о содержании сообщения) и тело сообщения.
10. http://www.slideshare.net/IgorShkulipa 10
Форма запроса
Клиент отсылает серверу запрос в одной из двух форм: в полной или
сокращенной. Запрос в первой форме называется соответственно
полным запросом, а во второй форме – простым запросом.
В качестве метода могут быть указаны GET, POST, HEAD, PUT, DELETE и
другие.
В качестве запрашиваемого URI чаще всего используется URL-адрес
ресурса.
Пример простого запроса:
GET http://somewebsite.com/
Здесь GET – это метод доступа, т.е. метод, который должен быть
применен к запрашиваемому ресурсу, а http://somewebsite.com/ – это
URL-адрес запрашиваемого ресурса.
Полный запрос содержит строку состояния, несколько заголовков
(заголовок запроса, общий заголовок или заголовок содержания) и,
возможно, тело запроса.
11. http://www.slideshare.net/IgorShkulipa 11
Методы
Любой запрос клиента к серверу должен начинаться с указания метода.
Метод сообщает о цели запроса клиента. Протокол HTTP
поддерживает достаточно много методов, но реально используются
только три: POST, GET и HEAD.
Метод GET позволяет получить любые данные, идентифицированные с
помощью URI в запросе ресурса. Если URI указывает на программу, то
возвращается результат работы программы, а не ее текст (если,
конечно, текст не есть результат ее работы). Дополнительная
информация, необходимая для обработки запроса, встраивается в сам
запрос (в строку статуса).
При использовании метода GET в поле тела ресурса возвращается
собственно затребованная информация (текст HTML-документа,
например).
Существует разновидность метода GET – условный GET. Этот метод
сообщает серверу о том, что на запрос нужно ответить, только если
выполнено условие, содержащееся в поле if-Modified-Since заголовка
запроса. Если говорить более точно, то тело ресурса передается в
ответ на запрос, если этот ресурс изменялся после даты, указанной в
if-Modified-Since.
12. http://www.slideshare.net/IgorShkulipa 12
Методы HEAD и POST
Метод HEAD аналогичен методу GET, только не возвращает тело ресурса
и не имеет условного аналога. Метод HEAD используют для получения
информации о ресурсе. Это может пригодиться, например, при
решении задачи тестирования гипертекстовых ссылок.
Метод POST разработан для передачи на сервер такой информации, как
аннотации ресурсов, новостные и почтовые сообщения, данные для
добавления в базу данных, т.е. для передачи информации большого
объема и достаточно важной. В отличие от методов GET и HEAD, в
POST передается тело ресурса, которое и является информацией,
получаемой из полей форм или других источников ввода.
13. http://www.slideshare.net/IgorShkulipa 13
Другие методы HTTP-запросов
Метод Описание
PUT Сохранить веб-страницу
DELETE Удалить веб-страницу
TRACE Отослать назад запрос
CONNECT Рассчитан на работу с HTTPS протоколом
OPTIONS Отобразить параметры
14. http://www.slideshare.net/IgorShkulipa 14
HTTP в Qt
Qt предоставляет класс QHttp для реализации стороны клиента HTTP-
протокола. Использование этого класса очень похоже на
использование класса QFtp.
Пример демонстрирует запись растрового изображения, находящегося на
www.geocities.ru/mslerm/images, в текущую директорию под именем
qtbook.gif.
QFile file("book.gif");
QHttp http;
if (file.open(QIODevice::WriteOnly))
{
http.setHost("www.geocities.com");
http.get("/mslerm/images/qtbook.gif", &file);
http.close();
file.close();
}
15. http://www.slideshare.net/IgorShkulipa 15
Протокол UDP
UDP (User Datagram Protocol, Протокол дейтаграмм пользователя)
предназначен для обмена дейтаграммами между процессами компьютеров,
входящих в единую сеть с коммутацией пакетов. В качестве протокола
нижнего уровня UDP-протокол использует IP.
Протокол UDP предоставляет прикладным программам возможность отправлять
сообщения другим приложениям, используя минимальное количество
параметров протокола. Этот протокол не обеспечивает достоверность
доставки пакетов, защиты дублирования данных или надежности от сбоев в
передаче. За исключением параметров приложения - номеров портов
отправителя и получателя пакета, UDP практически ничего не добавляет к
IP-дейтаграмме.
Протокол UDP намного проще, чем TCP и полезен в ситуациях, когда мощные
механизмы обеспечения надежности протокола TCP не требуются или будут
только помехой для решения определенного рода задач, например,
аутентификации пользователей.
Преимущество протокола UDP состоит в том, что он требует минимум установок
и параметров для соединения двух процессов между собой. Этот протокол
используется при работе Серверов Доменов (Name Servers), при работе
протокола TFTP (Trivial File Transfer, Тривиальный протокол передачи
данных), работе с SNMP и построении систем аутентификации.
16. http://www.slideshare.net/IgorShkulipa 16
Структура UDP пакета
• Source Port (16 бит). Порт отправителя. Это поле может содержать
номер порта, с которого был отправлен пакет, когда это имеет
значение (например отправитель ожидает ответа). Если это поле не
используется, оно заполняется нулями.
• Destination Port (16 бит). Порт назначения - это порт компьютера, на
который пакет будет доставлен.
• Length (16 бит). Поле длины. Длина (в байтах) этой дейтаграммы,
включая заголовок и данные. (Минимальное значение этого поля
равно 8).
• Checksum (16 бит). Поле контрольной суммы. Контрольная сумма
UDP-пакета представляет собой побитное дополнение 16-битной
суммы 16-битных слов (аналогично TCP). В вычислении участвуют:
данные пакета, заголовок UDP-пакета, псевдозаголовок (информация
от IP-протокола), поля выравнивания по 16-битной границе
(нулевые).
18. http://www.slideshare.net/IgorShkulipa 18
UDP в Qt
Qt предоставляет класс QUdpSocket для реализации обмена
датаграммами по протоколу UDP. Обмен датаграммами реализован в
виде методов readDatagram() и writeDatagram().
Пример:
QUdpSocket* udpSocket = new QUdpSocket(this);
udpSocket->bind(QHostAddress::LocalHost, 7755);
connect(udpSocket, SIGNAL(readyRead()),
this, SLOT(readPendingDatagrams()));
while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
udpSocket->readDatagram(datagram.data(),
datagram.size(), &sender, &senderPort);
DoSomethingWithDatagram(datagram);
}
19. http://www.slideshare.net/IgorShkulipa 19
Протокол TCP
Протокол TCP (Transmission Control Protocol, Протокол контроля передачи)
обеспечивает сквозную доставку данных между прикладными процессами,
запущенными на узлах, взаимодействующих по сети.
TCP - надежный байт-ориентированный (byte-stream) протокол с
установлением соединения. TCP находится на транспортном уровне стека
TCP/IP, между протоколом IP и собственно приложением. Протокол IP
занимается пересылкой дейтаграмм по сети, никак не гарантируя доставку,
целостность, порядок прибытия информации и готовность получателя к
приему данных; все эти задачи возложены на протокол TCP.
При получении дейтаграммы, в поле Protocol которой указан код протокола
TCP (6), модуль IP передает данные этой дейтаграммы модулю TCP. Эти
данные представляют собой TCP-сегмент, содержащий TCP-заголовок и
данные пользователя (прикладного процесса). Модуль TCP анализирует
служебную информацию заголовка, определяет, какому именно процессу
предназначены данные пользователя, проверяет целостность и порядок
прихода данных и подтверждает их прием другой стороне. По мере
получения правильной последовательности неискаженных данных
пользователя они передаются системному процессу.
21. http://www.slideshare.net/IgorShkulipa 21
Сокетное соединение
Сокет — это устройство пересылки данных с одного конца связи на
другой. Другой конец может принадлежать процессу, работающему на
локальном компьютере, а может располагаться и на удаленном
компьютере, подключенному к Интернету и расположенному в другом
полушарии Земли. Сокетное соединение — это соединение типа точка-
точка (point to point), которое производится между двумя процессами.
Класс QTcpSocket содержит набор методов для работы с TCP. С его
помощью можно реализовать поддержку для стандартных сетевых
протоколов, таких как: HTTP, FTP, POP3, SMTP, и даже для своих
собственных протоколов. Этот класс унаследован от класса
QAbstractSocket, который, в свою очередь, наследует класс
QIODevice. А это значит, что для доступа (чтения и записи) к его
объектам необходимо применять все методы класса QIODevice и
использовать классы потоков QDataStream или QTextStream.
Работа класса QTcpSocket асинхронна, что дает возможность
избежать блокирования приложения в процессе его работы.
23. http://www.slideshare.net/IgorShkulipa 23
Класс сервера
class ChatServer: public QObject
{
Q_OBJECT
public:
ChatServer(int port);
// Запуск сервера и связывание сигналов с методами
void Run();
// Очередь сообщений пуста
bool NoMessages();
// Возвращает первое сообщение из очереди
ChatMessage GetMessage();
public:
// Отключить клиента
void DisconnectClient();
// Подключить клиента
void ConnectNewClient();
// Получить сообщения от всех клиентов и добавить в очередь
void ReadClients();
// Отправить сообщение всем клиентам
void SendAll(ChatMessage message);
36. http://www.slideshare.net/IgorShkulipa 36
Лабораторная работа №7. Клиент-серверный тетрис
Реализовать «клиент-серверный тетрис».
Функции сервера:
• хранение базы данных игроков (лабораторная работа №5)
• обработка авторизации/регистрации
• прием, обработка и добавление в базу локальных данных игроков
в формате XML (лабораторная работа №6)
Функции клиента:
• игра
• авторизация/регистрация
• соединение с сервером и отправка данных
• если сервер недоступен, то сохранение статистики игры в XML
• при возобновлении соединения – отправка XML на сервер