You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1.[Transmission Control Protocol — TCP](#org0185056)
7
-
2.[User Datagram Protocol — UDP](#orga3ceb8c)
4
+
1.[Введение](#org82d7079)
5
+
2.[TCP и UDP](#org2157ab9)
6
+
1.[Transmission Control Protocol — TCP](#orgc5dc4b2)
7
+
2.[User Datagram Protocol — UDP](#org1d198a9)
8
+
3.[Самый простой сервер](#org23f420d)
8
9
9
10
10
11
11
-
<aid="org504f6ba"></a>
12
+
<aid="org82d7079"></a>
12
13
13
14
# Введение
14
15
@@ -29,14 +30,14 @@
29
30
На этом вступление окончено. Теперь вы готовы приступить к погружению в сетевое программирование на C++.
30
31
31
32
32
-
<aid="orgd89f8a1"></a>
33
+
<aid="org2157ab9"></a>
33
34
34
35
# TCP и UDP
35
36
36
37
Существует два основных протокола транспортного уровня, которые мы будем использовать — TCP и UDP. Протокол — это набор соглашений о том, как должны передаваться данные по сети.
37
38
38
39
39
-
<aid="org0185056"></a>
40
+
<aid="orgc5dc4b2"></a>
40
41
41
42
## Transmission Control Protocol — TCP
42
43
@@ -48,7 +49,7 @@ TCP-соединение очень похоже на файл: мы откры
48
49
Другими словами, файл предоставляет вам произвольный доступ, в то время как TCP-соединение представляет собой двунаправленный последовательный поток.
49
50
50
51
51
-
<aid="orga3ceb8c"></a>
52
+
<aid="org1d198a9"></a>
52
53
53
54
## User Datagram Protocol — UDP
54
55
@@ -63,3 +64,61 @@ TCP-соединение очень похоже на файл: мы откры
63
64
64
65
Это все, что вам необходимо знать о протоколах на данный момент. Значит, мы можем двигаться дальше.
65
66
67
+
68
+
<aid="org23f420d"></a>
69
+
70
+
# Самый простой сервер
71
+
72
+
Согласно [Википедии](https://ru.wikipedia.org/wiki/Сервер_(программное_обеспечение)),
73
+
74
+
> Сервер — программный компонент вычислительной системы, выполняющий сервисные (обслуживающие) функции по запросу клиента, предоставляя ему доступ к определённым ресурсам или услугам.
75
+
76
+
Это определение очень точно подмечает тот факт, что сервер — это всего лишь приложение, которое получает какие-то данные от других приложений и возвращает некоторые данные обратно.
77
+
78
+
Мы начнем с самого простого сервера, который приходит на ум — эхо UDP-сервер. Он выполняет следующие действия:
79
+
80
+
- Получает любые данные, которые были отправлены на UDP-порт 15001.
81
+
- Отправляет полученные данные обратно отправителю «как есть».
82
+
83
+
На самом деле вы можете выбрать практически любой порт для вашего сервера. Существует множество часто используемых портов для различных служб, которые вы можете найти здесь: [Список портов TCP и UDP](https://ru.wikipedia.org/wiki/Список_портов_TCP_и_UDP). Однако, как правило, только несколько из этих служб используется одновременно в недавно установленной ОС.
84
+
85
+
Теперь давайте взглянем на следующий [исходный код](./code/simple_server.cpp):
Вам даже не обязательно отдельно скачивать `.cpp` файл сервера, поскольку вышеприведенный код — это полноценный эхо UDP-сервер. Мы не реализовали логирование и обработку ошибок, чтобы код выглядел максимально просто. Об обработке ошибок мы поговорим позднее. Давайте разберемся, что происходит в этом коде:
108
+
109
+
-`boost::asio::io_context` — основной поставщик услуг ввода-вывода. В данный момент вы можете рассматривать его как исполнителя (executor) запланированных задач. Вы поймете его назначение сразу после того, как мы перейдем к асинхронному потоку управления, что произойдет очень скоро.
110
+
-`boost::asio::ip::udp::endpoint` — это пара IP-адреса и порта.
111
+
-`boost::asio::ip::udp::socket` — это сокет. Вы можете рассматривать его как дескриптор файла, предназначенный для сетевого взаимодействия. Обычно, когда вы открываете файл, вы получаете дескриптор файла. Когда вы взаимодействуете по сети, вы используете сокет.
112
+
- Каждый сокет прикреплен к некоторому `io_context`, а потому каждый сокет конструируется с помощью ссылки на `io_context`. Второй параметр конструктора сокета — `endpoint` — IP-адрес и порт, который используется для получения входящих дейтаграмм (в случае UDP) или соединений (в случае TCP).
113
+
-`boost::asio::ip::udp::v4()` возвращает объект, который в данный момент вы должны рассматривать как просто сетевой интерфейс UDP по умолчанию.
114
+
-`boost::asio::buffer()` — это представление буфера, которое содержит указатель и размер, причем это представление не владеет памятью. В нашем случае оно указывает на массив `char`.
115
+
-`socket::receive_from` ожидает входящий UDP-пакет, заполняет `buffer` полученными данными, а также заполняет `sender` информацией об отправителе, которая также включает в себя пару IP-адреса и порта.
116
+
-`socket::send_to` отправляет UDP-пакет, используя данные из представления буфера. Получатель пакета передается вторым аргументом. В нашем случае получателем является отправитель, поскольку речь идет об эхо-сервере.
117
+
118
+
Итак, мы сделали следующее:
119
+
120
+
- Создали UDP-сокет и настроили его на ожидание UDP-пакетов на порту 15001.
121
+
- Запустили бесконечный цикл, в котором ожидаем входящие UDP-пакеты, а после получения отправляем их обратно отправителю.
122
+
123
+
Поздравляем! Вы только что создали ваш первый сервер с помощью C++ и Boost.Asio!
Copy file name to clipboardExpand all lines: tutorial.org
+54Lines changed: 54 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,3 +40,57 @@ TCP-соединение очень похоже на файл: мы откры
40
40
Как вы можете понять, UDP немного сложнее в использовании, чем TCP. Тем не менее, у UDP есть свои преимущества, которые мы обсудим позднее.
41
41
42
42
Это все, что вам необходимо знать о протоколах на данный момент. Значит, мы можем двигаться дальше.
43
+
44
+
* Самый простой сервер
45
+
46
+
Согласно [[https://ru.wikipedia.org/wiki/Сервер_(программное_обеспечение)][Википедии]],
47
+
#+begin_quote
48
+
Сервер — программный компонент вычислительной системы, выполняющий сервисные (обслуживающие) функции по запросу клиента, предоставляя ему доступ к определённым ресурсам или услугам.
49
+
#+end_quote
50
+
51
+
Это определение очень точно подмечает тот факт, что сервер — это всего лишь приложение, которое получает какие-то данные от других приложений и возвращает некоторые данные обратно.
52
+
53
+
Мы начнем с самого простого сервера, который приходит на ум — эхо UDP-сервер. Он выполняет следующие действия:
54
+
- Получает любые данные, которые были отправлены на UDP-порт 15001.
55
+
- Отправляет полученные данные обратно отправителю «как есть».
56
+
57
+
На самом деле вы можете выбрать практически любой порт для вашего сервера. Существует множество часто используемых портов для различных служб, которые вы можете найти здесь: [[https://ru.wikipedia.org/wiki/Список_портов_TCP_и_UDP][Список портов TCP и UDP]]. Однако, как правило, только несколько из этих служб используется одновременно в недавно установленной ОС.
58
+
59
+
Теперь давайте взглянем на следующий [[./code/simple_server.cpp][исходный код]]:
Вам даже не обязательно отдельно скачивать ~.cpp~ файл сервера, поскольку вышеприведенный код — это полноценный эхо UDP-сервер. Мы не реализовали логирование и обработку ошибок, чтобы код выглядел максимально просто. Об обработке ошибок мы поговорим позднее. Давайте разберемся, что происходит в этом коде:
83
+
- ~boost::asio::io_context~ — основной поставщик услуг ввода-вывода. В данный момент вы можете рассматривать его как исполнителя (executor) запланированных задач. Вы поймете его назначение сразу после того, как мы перейдем к асинхронному потоку управления, что произойдет очень скоро.
84
+
- ~boost::asio::ip::udp::endpoint~ — это пара IP-адреса и порта.
85
+
- ~boost::asio::ip::udp::socket~ — это сокет. Вы можете рассматривать его как дескриптор файла, предназначенный для сетевого взаимодействия. Обычно, когда вы открываете файл, вы получаете дескриптор файла. Когда вы взаимодействуете по сети, вы используете сокет.
86
+
- Каждый сокет прикреплен к некоторому ~io_context~, а потому каждый сокет конструируется с помощью ссылки на ~io_context~. Второй параметр конструктора сокета — ~endpoint~ — IP-адрес и порт, который используется для получения входящих дейтаграмм (в случае UDP) или соединений (в случае TCP).
87
+
- ~boost::asio::ip::udp::v4()~ возвращает объект, который в данный момент вы должны рассматривать как просто сетевой интерфейс UDP по умолчанию.
88
+
- ~boost::asio::buffer()~ — это представление буфера, которое содержит указатель и размер, причем это представление не владеет памятью. В нашем случае оно указывает на массив ~char~.
89
+
- ~socket::receive_from~ ожидает входящий UDP-пакет, заполняет ~buffer~ полученными данными, а также заполняет ~sender~ информацией об отправителе, которая также включает в себя пару IP-адреса и порта.
90
+
- ~socket::send_to~ отправляет UDP-пакет, используя данные из представления буфера. Получатель пакета передается вторым аргументом. В нашем случае получателем является отправитель, поскольку речь идет об эхо-сервере.
91
+
92
+
Итак, мы сделали следующее:
93
+
- Создали UDP-сокет и настроили его на ожидание UDP-пакетов на порту 15001.
94
+
- Запустили бесконечный цикл, в котором ожидаем входящие UDP-пакеты, а после получения отправляем их обратно отправителю.
95
+
96
+
Поздравляем! Вы только что создали ваш первый сервер с помощью C++ и Boost.Asio!
0 commit comments