Программирование передачи информации между компьютерами по сети
Протокол TCP
Алгоритм работы с серверным сокетом
Пример
781.83K
Категория: ПрограммированиеПрограммирование

Программирование передачи информации между компьютерами по сети. Клиент-серверные приложения

1. Программирование передачи информации между компьютерами по сети

ПРОГРАММИРОВАНИЕ ПЕРЕДАЧИ
ИНФОРМАЦИИ
МЕЖДУ КОМПЬЮТЕРАМИ ПО СЕТИ
КЛИЕНТ-СЕРВЕРНЫЕ ПРИЛОЖЕНИЯ

2.

Компьютер в сети называется узел (хост) и имеет уникальный
адрес, который называется IP (internrt pointer). IP – адрес состоит
из 4 целых чисел от 0 до 255, разделенных точкой. Некоторые
адреса имеют специальное назначение, например 127.0.0.1 –
localhost – локальный адрес текущего компьютера.
192.168.XXX.XXX – адрес компьютера внутри локальной сети.
Но знать IP – адрес недостаточно, поскольку обмениваются
информацией не компьютеры сами по себе, а приложения,
работающие на них. Каждое программное приложение должно
иметь свой номер – “номер порта”. Порт – это логическое
соединение, через которое принимаются или отправляются
данные.

3.

Большинство стандартных приложений имеют стандартные номера, например почтовый сервис привязан к порту 25 (как говорят «слушает порт 25»), веб-сервис привязан к порту 80, FTP – к 21 и
т.д.
Номера портов до 1024 зарезервированы (заняты). Есть исключения, например 3128 – порт прокси-сервера.
Передача информации между компьютерами (точнее между
процессами) осуществляется через сокеты. Socket (гнездо, разъем) с точки зрения программы – это объект, осуществляющий пе-
ресылку данных с одного конца линии связи на другой, от одного
процесса к другому.
Основными параметрами сокета являются номер компьютера и
номер порта, эта комбинация идентифицирует сокет.

4.

Компьютеры по сети обмениваются пакетами, которые содержат
адрес отправителя, адрес получателя и собственно данные (+служебная информация).
Как правило взаимодействие осуществляется по схеме клиентсервер: клиент запрашива-ет какую-либо информацию, а
сервер принимает запрос, обрабатывает его и отсылает клиенту
результат.
Обмен информацией по сети определяется протоколами.
Протокол – это набор соглашений и правил обмена данными
между программами. Протокол определяет очередность дейст-
вий, позволяющую осуществлять соединение и обмен данными
между устройствами и процессами. Порт – это один из параметров протокола.

5.

Протоколы бывают разных уровней и работают друг с другом в
стеке: протокол, располагающийся на уровне выше, работает
поверх нижнего.
Например: IP – протокол сетевого уровня. Задача этого уровня –
доставка пакетов от компьютера-отправителя к компьютеру-получателю. Номера портов на сетевом уровне не используются.
Какому порту адресован пакет, был ли он доставлен, на этом
уровне не известно.
TCP и UDP – протоколы транспортного уровня, они используют
номер порта.
UDP – это протокол без установления соединения с негарантированной доставкой пакетов (типа: крикнул что-нибуь, а услышат тебя
или нет – неважно). Сокеты, работающие по этому протоколу,
называются дейтаграммные.

6.

TCP – протокол с установлением соединения и гарантированной
доставкой пакетов. Сначала производится обмен специальными
пакетами для установления соединения. Далее по этому соеди-
нению туда и обратно отсылаются пакеты, причем с проверкой,
дошел ли пакет до получателя. Если пакет не дошел, то он посылается повторно. Сооответствующие сокеты называются поточ-
ными.
Над транспортным уровнем находится прикладной уровень. На
этом уровне работают такие протоколы как http, ftp и другие.

7. Протокол TCP

ПРОТОКОЛ TCP
Сокет TCP может быть серверным или клиентским. Первый прослушивает порт с некоторым номером, ожидая подключения со
стороны клиентов, а второй (со стороны клиента) пытается подключиться к серверному сокету.
Приняв запрос на подключение, процесс – сервер создает для
нового клиента со своей стороны также клиентский сокет, через
который продолжает общаться с клиентом.
Сокеты могут работать в блокирующем и неблокирующем ре-
жиме.

8.

В первом случае выполнение потока, в котором работает сокет, блоки-
руется до окончания выполнения очередной операции. Во втором случае
используется программирование, управляемое событиями.
В библиотеке Qt для работы с сокетами имеется модуль
QtNetwork, который необходимо подключит командой #include.
Перед компиляцией программы в файле проекта *pro необходимо добавить строку:
QT += network

9. Алгоритм работы с серверным сокетом

АЛГОРИТМ РАБОТЫ С СЕРВЕРНЫМ
СОКЕТОМ
• Создать экземпляр класса QTcpServer;
• Перевести сервер в слушающее состояние.
• Перевести сервер в состояние ожидания запроса на
подключение.
Когда клиент подключился:
• Создать сокет для связи с клиентом (с помощью класса
QTcpSocket) и проинициализировать его.
• Ждать прихода запроса от клиента.
• Если данные пришли, прочитать их.

10. Пример

ПРИМЕР
Консольное приложение:
эхо-сервер в блокирующем режиме
Создать консольное приложение Qt.
стереть лишние команды из файла main.cpp
файл main.cpp
#include <iostream>
#include <QTextCodec>
#include <QtNetwork>
#define STR(s) ((codec->fromUnicode(s)).constData())
using namespace std;

11.

int main(int, char**)
{
QTextCodec* codec = QTextCodec::codecForName("CP866");
//qDebug() << "Отладка";
//QTextCodec::setCodecForLocale(QTextCodec::codecForName("CP866"));
//cout << QString::fromUtf8("Проверка:\n").toLocal8Bit().data() << endl;
// qDebug() << "Отладка"; // Выводит в то же окно, что и cout
QTcpServer server;
server.listen(QHostAddress::Any, 1234);
cout << STR("Сервер запущен\n");
// каждые 5 сек выводится сообщение:
while (!server.waitForNewConnection(5000))
// все функции wait блокируют работу потока
cout << STR("Ожидание запроса на подключение клиента\n");

12.

QTcpSocket* client; // Клиентский сокет
QHostAddress addr; // Адрес клиента
QByteArray block; // Блок для обмена данными
/*Для подтверждения соединения с клиентом необходимо вызвать метод
nextPendingConnection(), который возвратит сокет, посредством кото-
рого можно осуществлять дальнейшую связь с клиентом: */
client = server.nextPendingConnection(); //pending - ожидающий
// подключение произошло, создаем для него новый сокет:
addr = client->peerAddress(); // определяем адрес клиента
cout <<STR(QString("Подключился клиент с адреса %1\n"). arg(
addr.toString()));

13.

forever // позволяет повторить процесс получения строки
{
forever // ожидание поступления данных
{
if (!client || !client->isValid() || client->state() ==
QAbstractSocket::UnconnectedState)
{
cout << STR("Клиент отключился\n");
return 0;
}
if (client->waitForReadyRead(1000))
// в течение 1 сек ждем прихода данных
{
}
}
block = client->readAll(); // считываем данные
cout << block.data()<< endl;
break;

14.

client->write(STR("Эхо: "));
client->write(block);
client->write("\n");
client->waitForBytesWritten();
}
return 0;
}

15.

Консольное приложение: клиент
#include <iostream>
#include <QTextCodec>
#include <QtNetwork>
#define STR(s) (codec->fromUnicode(s).constData())
using namespace std;
int main(int , char **)
{
QTextCodec* codec = QTextCodec::codecForName("CP866");

16.

QTcpSocket socket;
QByteArray block;
QString server = "127.0.0.1";
int port = 1234;
socket.connectToHost(server, port);
cout << STR("Клиент запущен\n");
forever
{
cout << STR("Введите строку\n");
char text[81];
cin.getline(text, 80);
socket.write(text);
socket.waitForBytesWritten();

17.

forever
{
if (socket.waitForReadyRead(1000))
{
block = socket.readAll();
cout << block.data();
break;
}
}
}
return 0;
}
English     Русский Правила