hướng dẫn giả lập mạng ns-3. Chương 4

hướng dẫn giả lập mạng ns-3. Chương 4
chương 1,2
chap 3

4 Обзор концепции
4.1 Ключевые абстракции
4.1.1 Node (Узел)
4.1.2 Application (Приложение)
4.1.3 Channel (Канал)
4.1.4 Net Device (Сетевое устройство)
4.1.5 Топологические помощники
4.2 Первый скрипт ns-3
4.2.1 Boilerplate код
4.2.2 Подключаемые модули
4.2.3 Пространство имен ns3
4.2.4 Журналирование
4.2.5 Главная функция
4.2.6 Использование топологических помощников
4.2.7 Использование Application
4.2.8 Симулятор
4.2.9 Сборка вашего сценария
4.3 ns-3 Исходный код

Chương 4

Обзор концепции

Первое, что нам нужно сделать перед тем, как начать изучать или писать код ns‑3 — это объяснить несколько основных понятий и абстракций в системе. Многое из этого, для некоторых, может показаться очевидным, но мы рекомендуем уделить время для чтения этого раздела, чтобы убедиться, что вы начинаете на прочной основе.

4.1 Ключевые абстракции

В этом разделе мы рассмотрим некоторые термины, которые обычно используются в сети, но имеют определенное значение в ns‑3.

4.1.1 Node (Узел)

На интернет-жаргоне компьютерное устройство, которое подключается к сети, называется хостом или иногда конечной системой. По той причине, что ns‑3 — это симулятор сети, а не симулятор Интернет, мы намеренно не используем термин хост, так как это тесно связано с Интернетом и его протоколами. Вместо этого мы используем более общий термин, также используемый другими симуляторами, который берет начало в теории графов — узел (nút).

В ns-3 базовая абстракция вычислительного устройства называется узлом. Эта абстракция представлена в C++ классом Node. Класс NodeNode (узел) даёт методы для управления представлениями вычислительных устройств в симуляциях.

Вы должны понимать Node как компьютер, к которому вы добавите функциональность. Вы добавите такие вещи, как приложения, стеки протоколов и периферийные карты с драйверами, позволяющие компьютеру выполнять полезную работу. Мы используем такую же базовую модель в ns-3.

4.1.2 Application (Приложение)

Как правило, компьютерное программное обеспечение делится на два широких класса. Системное ПО организует различные компьютерные ресурсы такие как память, циклы процессора, диск, сеть и т. д. в соответствии с некоторой вычислительной моделью. Системное программное обеспечение обычно не использует эти ресурсы для выполнения задач, которые приносят непосредственную пользу пользователю. Пользователь для достижения определенной цели обычно запускает приложение, которое получает и использует ресурсы, контролируемые системным программным обеспечением.

Часто линия разделения между системным и прикладным программным обеспечением проводится при изменении уровня привилегий, которое происходит в ловушках операционной системы. В ns‑3 нет реальной концепции операционной системы и соответственно нет понятий уровней привилегий или системных вызовов. У нас, однако, есть идея приложения. Так же как в «реальном мире» для выполнения задач программные приложения работают на компьютерах, приложения ns‑3 работают на узлах ns‑3 для управления симуляциями в симулированном мире.

В ns‑3 базовой абстракцией для пользовательской программы, которая генерирует некоторую активность для моделирования, является приложение. Эта абстракция представлена в C++ классом Application (приложение). Класс Application предоставляет методы для управления в симуляциях представлениями нашей версии приложений уровня пользователя. От разработчиков ожидается, что для создания новых приложений они будут специализировать класс Application в смысле объектно-ориентированного программирования. В этом руководстве мы будем использовать специализации класса Application, называемые Ứng dụng UdpEchoClient и Ứng dụng UdpEchoServer. Как и следовало ожидать, эти приложения составляют набор приложений клиент/сервер используемых для генерации и эхо‑симуляции сетевых пакетов.

4.1.3 Channel (Канал)

В реальном мире можно подключить компьютер к сети. Часто среды, по которым передаются данные в этих сетях, называются каналами. Когда вы подключаете кабель Ethernet к розетке на стене, вы подключаете компьютер к каналу связи Ethernet. В смоделированном мире ns‑3 узел подключается к объекту, представляющему канал связи. Здесь основная абстракция коммуникационной подсети называется каналом и представляется в C++ классом Channel (канал).

lớp ChannelChannel предоставляет методы для управления взаимодействием объектов подсети и подключения к ним узлов. Каналы также могут быть специализированы разработчиками в смысле объектно-ориентированного программирования. Специализация канала может моделировать что-то простое как провод. Специализированный канал также может моделировать такие сложные вещи как большой Ethernet-коммутатор или трехмерное пространство, полное препятствий в случае беспроводных сетей.

Мы будем использовать в этом руководстве специализированные версии канала под названием CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel и WifiChannelWifiChannel. CsmaKênh, например, моделирует версию коммуникационной подсети которая реализует коммуникационную среду множественного доступа с контролем несущей. Это дает нам Ethernet-подобную функциональность.

4.1.4 Net Device (Сетевое устройство)

Раньше было так, что если вы хотите подключить компьютер к сети, вам нужно было купить определенный сетевой кабель и аппаратное устройство, называемое (в терминологии ПК) периферийной платой, которую необходимо установить в компьютер. Если на периферийной плате реализованы некоторые сетевые функции, их называли сетевыми интерфейсными платами или сетевыми картами. Сегодня большинство компьютеров поставляются с интегрированным оборудованием сетевого интерфейса, и пользователи не видят их как отдельные устройства.

Сетевая карта не будет работать без программного драйвера, управляющего её оборудованием. В Unix (или Linux), часть периферийного оборудования классифицируется как device. Устройства управляются с помощью драйверов устройств (device drivers), а сетевые устройства (NIC) управляются с использованием драйверов сетевых устройств (network device drivers) и имеют собирательное название сетевые устройства (net devices). В Unix и Linux вы обращаетесь к сетевым устройствам по таким именам, как например eth0.

В ns‑3 абстракция сетевого устройства охватывает как программный драйвер, так и моделируемое оборудование. При симуляции сетевое устройство «установлено» в узле, чтобы позволить ему связываться с другими узлами через каналы. Как и в реальном компьютере, узел может быть подключен к нескольким каналам через несколько устройств thiết bị mạng.

Сетевая абстракция устройства представлена в C++ классом thiết bị mạng. Lớp học thiết bị mạng обеспечивает методы управления соединениями с объектами Node и Channel; и могут быть специализированы разработчиками в смысле объектно-ориентированного программирования. В этом руководстве мы будем использовать несколько специализированных версий NetDevice под названиями Thiết bị CsmaNet, PointToPointNetThiết bị и WifiMạngThiết Bị. Так же, как сетевой адаптер Ethernet предназначен для работы с сетью Ethernet, Thiết bị CsmaNet предназначен для работы с CsmaKênh, PointToPointNetThiết bị предназначен для работы с Điểm Đến ĐiểmKênhWifiMạngThiết Bị — предназначен для работы с Kênh Wifi.

4.1.5 Топологические помощники

В реальной сети вы найдете хост-компьютеры с добавленными (или встроенными) сетевыми картами. В ns‑3 мы бы сказали, что вы будете видеть узлы с подключенными NetDevices. В большой моделируемой сети вам нужно будет организовать соединения между множеством объектов Node, thiết bị mạng и Kênh.

Поскольку подключение NetDevices к узлам, NetDevices к каналам, назначение IP-адресов и т.д. в ns‑3 являются общей задачей, то чтобы делать это как можно проще, мы предоставляем так называемых топологических помощников. Например, для создания NetDevice необходимо выполнить множество операций ядра ns‑3, добавить MAC-адрес, установить это сетевое устройство в Node, настроить стек протоколов узла, а затем подключить NetDevice к Channel. Еще больше операций будет необходимо, чтобы подключить несколько устройств к многоточечным каналам, а затем соединить отдельные сети в объединенную сеть (Internetworks). Мы предоставляем вспомогательные объекты топологии, которые для вашего удобства объединяют эти многочисленные операции в простую в использовании модель.

4.2 Первый скрипт ns-3

Если вы установили систему, как было предложено выше, у вас будет релиз ns‑3 в директории с именем repos в вашей домашней директории. Перейдите в директорию phát hành

Если у вас нет такой директории, значит вы при сборке релизной версии ns‑3 не указали выходную директорию, выполните сборку так:
$ ./waf configure —build-profile=release —out=build/release,
$ ./waf bản dựng

там вы должны увидеть структуру директории похожую на следующую:

AUTHORS       examples      scratch       utils       waf.bat*
bindings      LICENSE       src           utils.py    waf-tools
build         ns3           test.py*      utils.pyc   wscript
CHANGES.html  README        testpy-output VERSION     wutils.py
doc           RELEASE_NOTES testpy.supp   waf*        wutils.pyc

Đi tới thư mục ví dụ / hướng dẫn. Вы должны увидеть расположенный там файл с именем đầu tiên.cc. Это скрипт, который создаст простое соединение точка-точка между двумя узлами и передаст один пакет между узлами. Давайте посмотрим на этот скрипт построчно, для этого откроем first.cc в вашем любимом редакторе.

4.2.1 Boilerplate код
Первая строка в файле — это строка режима редактора emacs. Она говорит emacs об условностях форматирования (стиль кодирования), которые мы использовать в нашем исходном коде.

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

Это всегда довольно спорный вопрос, поэтому мы должны внести ясность, что бы сразу же убрать его с дороги. Проект ns‑3, как и большинство крупных проектов, принял стиль кодирования, которому должен соответствовать весь предоставленный код. Если вы хотите внести свой код в проект, вам в конечном итоге придется соответствовать стандарту кодирования ns‑3, как описано в файле doc / codingstd.txt или показанный на веб-странице проекта: https://www.nsnam.org/develop/contributing-code/coding-style/.

Мы рекомендуем вам привыкнуть к внешнему виду кода ns‑3 и применять этот стандарт всякий раз, когда вы работаете с нашим кодом. Вся команда разработчиков и контрибуторы согласились с этим после некоторого ворчания. Строка режима emacs, приведенная выше, упрощает правильное форматирование, если вы используете редактор emacs.

Симулятор ns‑3 лицензируется с использованием Giấy phép Công cộng GNU. Вы увидите соответствующий юридический заголовок GNU в каждом файле дистрибутива ns‑3. Часто вы можете увидеть уведомление об авторских правах для одного из участвующих учреждений в проекте ns‑3 выше текста GPL и автора, показанное ниже.

/* 
* This program is free software; you can redistribute it and/or modify 
* it under the terms of the GNU General Public License version 2 as 
* published by the Free Software Foundation; 
*
* This program is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
* GNU General Public License for more details. 
* 
* You should have received a copy of the GNU General Public License 
* along with this program; if not, write to the Free Software 
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
*/

4.2.2 Подключаемые модули

Собственно код начинается с ряда операторов включения (bao gồm).

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"

Чтобы помочь нашим пользователям сценариев высокого уровня справиться с большим количеством заголовочных файлов, присутствующих в системе, мы группируем их в соответствии с их использованием в большие модули. Мы предоставляем один заголовочный файл, который будет рекурсивно загружать все заголовочные файлы, используемые в данном модуле. Вместо того, чтобы искать, какой именно заголовок вам нужен, и, возможно получить правильный список зависимостей, мы даем вам возможность загружать группу файлов с большой степенью детализации. Это не самый эффективный подход, но он, безусловно, делает написание сценариев намного проще.

Каждый из включаемых файлов ns‑3 помещается в директорию с именем Ns3 (поддиректория сборки), чтобы во время процесса сборки избежать конфликтов имен файлов. Файл ns3 / core-module.h соответствует модулю ns‑3, который вы найдите в директории src / core в установленном вами релизе. В листинге этой директории вы найдете большое количество заголовочных файлов. Когда вы делаете сборку, Waf помещает общедоступные заголовочные файлы в директорию ns3 в поддиректорию xây dựng / gỡ lỗi

Если у вас нет такой директории, значит вы при сборке релизной версии ns‑3 не указали выходную директорию, выполните сборку так:
$ ./waf configure —build-profile=debug —out=build/debug
$ ./waf bản dựng
hoặc
$ ./waf configure —build-profile=optimized —out=build/optimized
$ ./waf bản dựng

hoặc xây dựng / tối ưu hóa, в зависимости от вашей конфигурации. Waf будет также автоматически генерировать включаемый файл модуля для загрузки всех общедоступных заголовочных файлов. Поскольку вы, конечно, неукоснительно следуете этому руководству, вы уже сделали

$ ./waf -d debug --enable-examples --enable-tests configure

чтобы настроить проект на выполнение отладочных сборок, включающих примеры и тесты. Вы также сделали

$ ./waf

чтобы собрать проект. Так что теперь, когда вы посмотрите в директорию ../../build/debug/ns3, то там, среди прочих, вы найдете заголовочные файлы четырех модулей, показанные выше. Вы можете взглянуть на содержимое этих файлов и обнаружить, что они включают в себя все публичные файлы используемые соответствующими модулями.

4.2.3 Пространство имен ns3

Следующая строка в скрипте đầu tiên.cc — это объявление пространства имен.

using namespace ns3;

Проект ns‑3 реализован в пространстве имен C++, которое называется ns3. Это группирует все ns‑3-связанные объявления в области видимости за пределами глобального пространства имен, которое, как мы надеемся, поможет в интеграции с другим кодом. Использование оператора C++ вводит пространство имен ns‑3 в текущий (глобальный) декларативный регион. Это причудливый способ сказать, что после этого объявления, вам не нужно будет вводить оператор разрешения ns3 :: scope перед всем кодом ns‑3, чтобы использовать его. Если вы не знакомы с пространствами имен, обратитесь к практически любому учебнику по C++ и сравните пространство имен ns3 с использованием пространства имен std и объявления using namespace std; в примерах работы с оператором вывода cout и потоками.

4.2.4 Журналирование

Следующая строка скрипта такая,

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Мы будем использовать это утверждение как удобное место для обсуждения нашей системы документирования doxygen. Если вы посмотрите на веб-сайт проекта ns‑3, вы найдете ссылку «Документация» (Documentation) на панели навигации. Если вы выберете эту ссылку, то окажетесь на нашей странице документации. Существует ссылка на «Последний релиз», которая приведет вас к документации для последней стабильной версии ns‑3. Если вы выберете ссылку «API Documentation», вы попадете на страницу документации API ns‑3.

С левой стороны страницы вы найдете графическое представление структуры документации. Хорошее место для начала — это «книга» Modules ns‑3 в дереве навигации ns‑3. Если вы раскроете Modules, вы увидите список документации модулей ns‑3. Как обсуждалось выше, концепция модуля здесь напрямую связана с включенными в модуль файлами выше. Подсистема журналирования (ведения журнала, логирования) ns‑3 обсуждается в разделе Использование модуля журналирования, поэтому мы вернемся к ней позже в этом руководстве, но Вы можете узнать о приведенном выше утверждении, посмотрев на модуль Trung tâm, а затем открыв книгу Công cụ gỡ lỗi, а затем выбрав страницу Logging. Кликните по Logging.

Теперь вы должны просмотреть документацию doxygen cho mô-đun Logging. В списке макросов в верхней части страницы вы увидите запись для NS_LOG_COMPONENT_DEFINE. Перед тем как перейти по ссылке, обязательно посмотрите «Подробное описание» модуля регистрации, чтобы понять его работу в целом. Чтобы сделать это вы можете прокрутить вниз или выбрать «More…» под диаграммой.

Как только у вас будет общее представление о том, что происходит, продолжайте и посмотрите документацию на конкретные NS_LOG_COMPONENT_DEFINE. Я не буду дублировать документацию здесь, но подводя итог, скажу, что эта строка объявляет компонент регистрации под названием FirstScriptVí dụ, который позволяет включать и отключать консоль регистрация сообщений по ссылке на имя.

4.2.5 Главная функция

В следующих строках скрипта вы увидите,

int 
main (int argc, char *argv[])
{ 

Это просто объявление основной функции вашей программы (скрипта). Как и в любой программе на C++, вам нужно определить главную функцию, она выполняется первой. Здесь нет ничего особенного. Ваш скрипт ns‑3 просто C++ программа. Следующая строка устанавливает разрешение по времени равное 1 наносекунде, что является значением по умолчанию:

Time::SetResolution (Time::NS);

Разрешение по времени или просто разрешение — это наименьшее значение времени, которое может быть использовано (наименьшая представимая разница между двумя значениями времени). Вы можете изменить разрешение ровно один раз. Механизм, обеспечивающий эту гибкость, потребляет память, поэтому, как только разрешение будет установлено явно, мы освобождаем память, предотвращая дальнейшие обновления. (Если вы не установите разрешение явно, то по умолчанию оно будет равно одной наносекунде, и память будет освобождена при начале симуляции.)

Следующие две строки сценария используются для включения двух компонентов ведения журнала, которые встроены в приложения EchoClient и máy chủ tiếng vang:

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);

Если вы прочитали документацию по компоненту Logging, вы увидите, что существует несколько уровней подробности регистрации/детализации, которые вы можете включить на каждом компоненте. Эти две строки кода включают ведение журнала отладки на уровень INFO для эхо-клиентов и серверов. На этом уровне приложение во время моделирования будет распечатывать сообщения при отправке и получении пакетов.

Теперь мы перейдем непосредственно к делу создания топологии и запуска симуляции. Мы задействуем объекты топологических помощников, чтобы сделать эту работу как можно проще.

4.2.6 Использование топологических помощников

Следующие две строки кода в нашем скрипте фактически создадут объекты Node ns‑3, которые будут представлять компьютеры в симуляция.

NodeContainer nodes;
nodes.Create (2);

Прежде чем мы продолжим, давайте найдем документацию для класса NútContainer. Еще один способ попасть в документацию для данного класса это через вкладку Các lớp học trên các trang doxygen. Если у вас уже открыт Doxygen, просто прокрутите вверх до верхней части страницы и выберите вкладку Classes. Вы должны увидеть новый набор вкладок, один из которых список классов. Под этой вкладкой вы увидите список всех классов ns‑3. Прокрутите вниз, до ns3 :: NodeContainer. Когда вы найдете класс, выберите его, чтобы перейти к документации для класса.

Как мы помним, одной из наших ключевых абстракций является узел. Он представляет компьютер, к которому мы собираемся добавить такие вещи, как стеки протоколов, приложения и периферийные карты. Топологический помощник NútContainer обеспечивает удобный способ создания, управления и доступа к любым объектам Node, которые мы создаем для запуска симуляции. Первый строка выше просто объявляет NútContainer, который мы называем nodes. Вторая строка вызывает метод Create для объекта nodes и просит контейнер создать два узла. Как описано в doxygen, контейнер запрашивает в системе ns‑3 создание двух объектов Node и сохраняет указатели на эти объекты у себя внутри.

Созданные в скрипте узлы, пока ничего не делают. Следующим шагом в построении топологии является подключение наших узлов к сети. Самая простая форма сети, которую мы поддерживаем, — это двухточечная связь между двумя узлами. Мы сейчас создадим такое соединение.

PointToPointTrợ giúp

Мы создаем двухточечное соединение, действуя по знакомому нам шаблону, используем топологический вспомогательный объект для выполнения низкоуровневой работы, необходимой для соединения. Напомним, что две наши ключевые абстракции thiết bị mạng и Kênh. В реальном мире эти термины примерно соответствуют периферийным картам и сетевым кабелям. Как правило, эти две вещи тесно связаны друг с другом, и никто не может рассчитывать на обмен, например, устройства Ethernet по беспроводному каналу. Наши топологические помощники следуют этой тесной связи и поэтому вы будете в этом сценарии использовать один объект PointToPointTrợ giúp для настройки и подключения ns‑3 объектов PointToPointNetThiết bị и Điểm Đến ĐiểmKênh. Следующие три строки в сценарии:

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); 
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

Первая строка,

PointToPointHelper pointToPoint;

создает в стеке экземпляр объекта PointToPointTrợ giúp. С точки зрения верхнего уровня следующая строка,

pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));

говорит объекту PointToPointTrợ giúp использовать значение «5 Мбит/с» (пять мегабит в секунду) в качестве «Tốc độ dữ liệu'.

С более конкретной точки зрения, строка «DataRate» соответствует тому, что мы называем атрибутом PointToPointNetThiết bị. Если вы посмотрите на doxygen для класса ns3 :: PointToPointNetDevice и в документации к методу GetTypeId вы найдете список атрибутов, определенных для устройства. Среди них будет атрибут «Tốc độ dữ liệu». Большинство видимых пользователем объектов ns‑3 имеют похожие списки атрибутов. Мы используем этот механизм для простой настройки симуляции без перекомпиляции, как вы увидите в следующем разделе.

Подобно «Tốc độ dữ liệu» в PointToPointNetDevice, вы найдете атрибут «Delay», связанный с PointToPointChannel. Финальная строка,

pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

nói PointToPointTrợ giúp использовать значение «2 мс» (две миллисекунды) в качестве значения задержки распространения по каналу точка-точка, который он впоследствии создает.

NetThiết BịContainer

На данный момент у нас в сценарии есть NútContainer, который содержит два узла. У нас есть PointToPointTrợ giúp, который подготовлен для создания объектов PointToPointNetThiết bị и соединения их с помощью объекта PointToPointChannel. Так же, как мы использовали для создания узлов вспомогательный объект топологии NodeContainer, мы попросим PointToPointTrợ giúp выполнить для нас работу, связанную с созданием, настройкой и установкой наших устройств. Нам потребуется список всех созданных объектов thiết bị mạng, поэтому мы используем NetThiết BịContainer для их хранения так же, как мы использовали NútContainer для хранения созданных нами узлов. Следующие две строки кода,

NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);

завершают настройку устройств и канала. Первая строка декларирует контейнер устройства, упомянутый выше, а вторая выполняет основную работу. Метод đặt một đối tượng PointToPointTrợ giúp mất NútContainer как параметр. Внутри NetThiết BịContainer для каждого узла находящегося в NútContainer создается (для связи точка-точка их должно быть ровно два) PointToPointNetThiết bị создается и сохраняется в контейнере устройства. Điểm Đến ĐiểmKênh создается, и к нему присоединяются два PointToPointNetThiết bị. После создания объектов, атрибуты хранившиеся в PointToPointTrợ giúp, используются для инициализации соответствующих атрибутов в созданных объектах.

После выполнения вызова pointToPoint.Install (nodes) у нас будет два узла, каждый с установленным сетевым устройством «точка-точка» и одним каналом «точка-точка» между ними. Оба устройства будут настроены на передачу данных со скоростью пять мегабит в секунду с задержкой передачи по каналу в две миллисекунды.

InternetNgăn XếpTrợ Giúp

Теперь у нас настроены узлы и устройства, но на наших узлах не установлены стеки протоколов. Следующие две строки кода позаботятся об этом.

InternetStackHelper stack;
stack.Install (nodes);

InternetNgăn XếpTrợ Giúp — представляет собой топологический помощник для интернет-стеков, подобно PointToPointHelper для двухточечных сетевые устройств. Метод đặt принимает NodeContainer в качестве параметра. При выполнении он установит Интернет-стек (TCP, UDP, IP и т. д.) на каждом узле контейнера.

Trình trợ giúp địa chỉ Ipv4

Затем нам нужно к наши устройства связать с IP-адресами. Мы предоставляем топологического помощника для управления распределением IP-адресов. Единственный видимый пользователю API — это установка базового IP-адреса и маски сети для использования при выполнении фактического распределения адресов (это делается на более низком уровне внутри помощника). Следующие две строки кода в нашем примере скрипта đầu tiên.cc,

Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");

декларируют вспомогательный объект адреса и говорят ему, что он должен начать выделять IP-адреса из сети 10.1.1.0, используя для определения битовую маску 255.255.255.0. По умолчанию выделенные адреса будут начинаться с единицы и увеличиваться монотонно, поэтому первый адрес, выделенный из этой базы, будет 10.1.1.1, затем 10.1.1.2 и т.д. В реальности, на низком уровне система ns‑3 запоминает все выделенные IP-адреса и генерирует фатальную ошибку, если вы случайно создали ситуацию когда один и тот же адрес будет сгенерирован дважды (кстати, эту ошибку трудно отладить).

Следующая строка кода,

Ipv4InterfaceContainer interfaces = address.Assign (devices);

выполняет фактическое назначение адреса. В ns‑3 мы устанавливаем связь между IP-адресом и устройством, используя объект Giao diện Ipv4. Так же, как нам иногда нужен список сетевых устройств, созданных помощником для дальнейшего использования, нам иногда нужен список объектов Giao diện Ipv4. Bộ chứa giao diện Ipv4 предоставляет эту функциональность.

Мы построили сеть точка-точка, с установленными стеками и назначенными IP-адресами. Теперь нам нужны в каждом узле приложения для генерации трафика.

4.2.7 Использование Application

Еще одна из основных абстракций системы ns‑3 — это Các Ứng Dụng (приложение). В этом сценарии мы используем две специализации базового класса Các Ứng Dụng ns‑3 под названием Ứng dụng UdpEchoServer и Ứng dụng UdpEchoClient. Как и в предыдущих случаях, мы используем вспомогательные объекты для настройки и управления базовыми объектами. Здесь мы используем UdpEchoMáy ChủTrợ Giúp и UdpEchoClientHelper объекты, чтобы сделать нашу жизнь проще.

UdpEchoMáy ChủTrợ Giúp

Следующие строки кода в нашем примере скрипта first.cc, используются для настройки приложения UDP эхо сервера на одном из узлов, которые мы создали ранее.

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));

Первая строка кода в приведенном выше фрагменте создаёт UdpEchoMáy ChủTrợ Giúp. Как обычно, это не приложение само по себе, это объект, который помогает нам создавать реальные приложения. Одно из наших соглашений — передавать необходимые атрибуты в конструктор вспомогательного объекта (помощника). В этом случае помощник не может сделать ничего полезного, если ему не предоставлен номер порта на котором сервер будет ожидать пакеты, этот номер также должен быть известен клиенту. В данном случае мы передаем конструктору помощника номер порта. Конструктор, в свою очередь, просто выполняет Đặt thuộc tính с переданным значением. Позже, при желании, с помощью SetAttribute вы сможете установить другое значение атрибута «Порт».

Подобно многим другим вспомогательным объектам, объект UdpEchoMáy ChủTrợ Giúp имеет метод đặt. Выполнение этого метода, фактически приводит к тому, что создается базовое приложение эхо-сервера и привязывается к узлу. Интересно, что метод đặt mất NútContainter в качестве параметра так же, как и другие đặt методы, которые мы видели.

Неявное преобразование C++, работающее здесь, принимает результат метода node.Get (1) (который возвращает умный указатель на объект узла — Ptr ) и использует его в конструкторе для анонимного объекта NútContainer, который затем передается методу đặt. Если вы не можете определить в C++ коде, метод с какой сигнатурой компилируется и выполняется, то ищите среди неявных преобразований.

Теперь мы видим, что echoServer.Cài đặt собирается установить приложение Ứng dụng UdpEchoServer на найденный в NútContainer, который мы используем для управления нашими узлами, узел с индексом 1. Метод đặt вернет контейнер, который содержит указатели на все приложения (в данном случае одно, поскольку мы передали анонимный NútContainer, содержащий один узел) созданный помощником.

Приложениям требуется указать момент запуска генерации трафика "bắt đầu" и может потребоваться дополнительно указать время, когда его остановить «stop». Мы предоставляем оба параметра. Эти времена устанавливаются с помощью методов Ứng DụngContainer Bắt đầu и Dừng. Эти методы принимают параметры типа Thời gian. В этом случае мы используем явную последовательность преобразований C++, чтобы взять C++ tăng gấp đôi 1.0 и преобразовать его в объект тns‑3 Time, использующий объект Seconds для перевода в секунды. Помните, что правила преобразования могут контролироваться автором модели, и C++ имеет свои собственные правила, поэтому вы не всегда можете рассчитывать на то, что параметры будут преобразованы так, как вы ожидали. Две строки,

serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));

приведет к тому, что приложение эхо-сервера запустится (включится автоматически) через одну секунду после начала симуляции и остановится (отключится) через десять секунд симуляции. В силу того, что мы объявили событие моделирования (событие остановки приложения), которое будет выполнено через десять секунд, то будет просимулировано не менее десяти секунд работы сети.

UdpEchoClientTrợ giúp

Клиентское приложение bỏ lỡ настраивается способом, практически аналогичным серверу. Существует базовый объект Ứng dụng UdpEchoClient, được quản lý
UdpEchoClientTrợ giúp.

UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));

ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));;

Однако для эхо-клиента нам нужно установить пять разных атрибутов. Первые два атрибута устанавливаются во время создания UdpEchoClientTrợ giúp. Мы передаем параметры, которые используются (внутри помощника) для установки атрибутов «RemoteAddress» и «RemotePort» в соответствии с нашим соглашением, о передаче необходимых параметров в конструктор помощника.

Напомним, что мы использовали Bộ chứa giao diện Ipv4 для отслеживания IP-адресов, которые мы присвоили нашим устройствам. Нулевой интерфейс в контейнере интерфейсов будет соответствовать IP-адресу нулевого узла в контейнере узлов. Первый интерфейс в контейнере интерфейсов соответствует IP-адресу первого узла в контейнере узлов. Итак, в первой строке кода (сверху) мы создаем помощника и сообщаем ему, что удаленным адресом клиента будет IP-адрес, назначенный узлу, на котором находится сервер. Мы также говорим, что нужно организовать отправку пакетов на девятый порт.

Атрибут «MaxPackets» сообщает клиенту максимальное количество пакетов, которое мы можем отправить во время моделирования. Атрибут «Interval» сообщает клиенту, как долго ждать между пакетами, и атрибут «PacketSize» сообщает клиенту, насколько велика должны быть полезная нагрузка пакета. Этой комбинацией атрибутов мы говорим клиенту отправить один 1024-байтовый пакет.

Как и в случае с эхо-сервером, мы устанавливаем эхо-клиенту атрибуты Bắt đầu и Dừng, но здесь мы запускаем клиент через секунду после включения сервера (через две секунды после начала симуляции).

4.2.8 Симулятор

На этом этапе нам нужно запустить симуляцию. Это делается с помощью глобальной функции Trình mô phỏng :: Chạy.

Simulator::Run ();

Когда мы ранее вызывали методы,

serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
... 
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));

мы фактически запланировали события в симуляторе на 1,0 секунды, 2,0 секунды и два события на 10,0 секунды. После вызова Trình mô phỏng :: Chạy, система начнет просматривать список запланированных событий и выполнять их. Сначала он запустит событие через 1,0 секунды, что активирует приложение эхо-сервера (это событие может, в свою очередь, запланировать много других событий). Затем он запустит событие, запланированное на t = 2,0 секунды, которое запустит приложение эхо-клиента. Опять же, это событие может запланировать еще много событий. Реализация события запуска в эхо-клиенте начнет этап передачи данных моделирования, отправив пакет на сервер.

Акт отправки пакета на сервер вызовет цепочку событий, которые будут автоматически запланированы за сценой и которые будут реализовывать механику отправки пакета эхо-сигналов в соответствии с параметрами синхронизации, которые мы установили в сценарии.

В итоге, поскольку мы отправляем только один пакет (напомним, атрибут Gói tối đa был установлен в единицу), цепочка событий инициированный этим единственным клиентским эхо-запросом закончится, и симуляция перейдет в режим ожидания. Как только это произойдет, оставшимися запланированными событиями будут события Dừng для сервера и клиента. Когда эти события выполнятся, событий для дальнейшей обработки не останется и Trình mô phỏng :: Chạy вернет управление. Моделирование завершено.

Осталось только прибрать за собой. Это делается путем вызова глобальной функции Trình mô phỏng :: Phá hủy. Поскольку вызывались функции помощников (или код низкого уровня ns‑3), которые организованы так, чтобы в симуляторе были вставлены хуки для уничтожения всех объектов, которые были созданы. Вам не требуется отслеживать какие-либо из этих объектов самостоятельно — все, что вам нужно было сделать это вызвать Trình mô phỏng :: Phá hủy и выйти. Система ns‑3 сделает эту трудную работу за вас. Оставшиеся строки нашего первого ns‑3 скрипта, first.cc, делают именно это:

Simulator::Destroy ();
return 0;
}

Когда симулятор остановится?

ns‑3 — симулятор дискретных событий (DE). В таком симуляторе каждое событие связано со временем его выполнения, а симуляция продолжается обработкой событий в порядке их возникновения по ходу симуляции. События могут стать причиной планирования будущих событий (например, таймер может перепланировать себя, чтобы закончить счет в следующем интервале).

Начальные события обычно инициируются объектом, например, IPv6 будет планировать определение сервисов в сети, запросы соседей и т.д. Приложение планирует первое событие отправки пакета и т.д. Когда событие обрабатывается, оно может генерировать ноль, одно или несколько событий. По мере выполнения симуляции, происходят события, просто заканчиваясь или порождая новые. Симуляция остановится автоматически, если очередь событий окажется пустой или будет обнаружен специальное событие Dừng. Sự kiện Dừng генерируется функцией Trình mô phỏng :: Dừng lại (остановить время).

Существует типичный случай, когда Simulator::Stop абсолютно необходима для остановки симуляции: когда есть самоподдерживающиеся события. Самоподдерживающиеся (или повторяющиеся) события — это события, которые всегда перепланируются. Как следствие, они всегда сохраняют очередь событий не пустой. Существует много протоколов и модулей, содержащих повторяющиеся события, например:

• FlowMonitor — периодическая проверка на потерянные пакеты;

• RIPng — периодическая трансляция обновления таблиц маршрутизации;

• и т.д.

Trong trường hợp này Trình mô phỏng :: Dừng lại необходим для корректной остановки симуляции. Кроме того, когда ns‑3 находится в режиме эмуляции, RealtimeSimulator используется, чтобы синхронизировать часы симуляции с часами машины, и Trình mô phỏng :: Dừng lại необходим для остановки процесса.

Многие из программ симуляции в учебнике не вызывают Trình mô phỏng :: Dừng lại явно, так как они завершаются автоматически с исчерпанием событий в очереди. Однако эти программы также примут вызов Simulator::Stop. Например, следующий дополнительный оператор в первом примере программы запланирует явную остановку на 11 секунде:

+ Simulator::Stop (Seconds (11.0));
  Simulator::Run ();
  Simulator::Destroy ();
  return 0;
}

Вышеуказанное фактически не изменит поведение этой программы, так как это конкретное моделирование естественным образом заканчивается через 10 секунд. Но если бы вы изменили время остановки в приведенном выше операторе с 11 секунд до 1 секунды, вы заметили бы, что моделирование останавливается до того, как любой вывод попадет на экран (поскольку вывод происходит примерно через 2 секунды времени симуляции).

Важно вызвать Simulator::Stop до вызова Simulator::Run; в противном случае Simulator::Run может никогда не вернуть управление основной программе для выполнения остановки!

4.2.9 Сборка вашего сценария

Мы сделали создание ваших простых скриптов тривиальным. Все, что вам нужно сделать, это поместить ваш скрипт в каталог scratch, и он будет автоматически собран, если вы запустите Waf. Давай попробуем. Вернетесь в каталог верхнего уровня и скопируйте ví dụ / hướng dẫn / first.cc vào danh mục xước

$ cd ../.. 
$ cp examples/tutorial/first.cc scratch/myfirst.cc

Теперь соберите свой первый пример сценария, используя WAF:

$ ./waf

Вы должны увидеть сообщения о том, что ваш первый пример был успешно создан.

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
[614/708] cxx: scratch/myfirst.cc -> build/debug/scratch/myfirst_3.o
[706/708] cxx_link: build/debug/scratch/myfirst_3.o -> build/debug/scratch/myfirst
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (2.357s)

Теперь вы можете запустить пример (обратите внимание, что если вы собираете свою программу в директории scratch, то и запускать его вы должны из xước):

$ ./waf --run scratch/myfirst

Вы должны увидеть похожий вывод:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.418s) Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

Здесь вы видите, что система сборки проверяет, что файл был собран, а затем запускает его. Вы видите запись компонент на эхо-клиенте указывает, что он отправил один 1024-байтовый пакет на эхо-сервер 10.1.1.2. Вы тоже см. компонент ведения журнала на эхо-сервере, чтобы сказать, что он получил 1024 байта от 10.1.1.1. Эхо-сервер молча повторяет пакет, и вы видите в журнале эхо-клиента, что он получил свой пакет обратно с сервера.

4.3 ns-3 Исходный код

Теперь, когда вы использовали некоторые из помощников ns‑3, вы можете взглянуть на некоторые исходные коды, которые реализует эту функциональность. Самый свежий код можно просмотреть на нашем веб-сервере по следующей ссылке: https://gitlab.com/nsnam/ns-3-dev.git. Там вы увидите сводную страницу Mercurial для нашего дерева разработки ns‑3. В верхней части страницы вы увидите несколько ссылок,

summary | shortlog | changelog | graph | tags | files

Идите дальше и выберите ссылку на файлы. Вот как будет выглядеть верхний уровень большинства наших репозиториев:

drwxr-xr-x                               [up]
drwxr-xr-x                               bindings python  files
drwxr-xr-x                               doc              files
drwxr-xr-x                               examples         files
drwxr-xr-x                               ns3              files
drwxr-xr-x                               scratch          files
drwxr-xr-x                               src              files
drwxr-xr-x                               utils            files
-rw-r--r-- 2009-07-01 12:47 +0200 560    .hgignore        file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1886   .hgtags          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1276   AUTHORS          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 30961  CHANGES.html     file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 17987  LICENSE          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 3742   README           file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 16171  RELEASE_NOTES    file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 6      VERSION          file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 88110  waf              file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 28     waf.bat          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 35395  wscript          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 7673   wutils.py        file | revisions | annotate

Наши примеры сценариев находятся в директории ví dụ. Если вы нажмете на примеры, вы увидите список поддиректорий. Один из файлов в поддиректории tutorial — first.cc. Если вы нажмете на đầu tiên.cc вы увидите код, который вы только что изучили.

Исходный код находится в основном в директории src. Вы можете просмотреть исходный код, нажав на имя директории или нажав на ссылку файлы справа от имени директории. Если вы кликнете на директория src, вы получите список поддиректорий src. Если вы затем кликнете по поддиректории core, вы найдете список файлов. Первый файл, который вы увидите (на момент написания этого руководства) — hủy bỏ.h. Если вы нажмете на ссылку hủy bỏ.h, вы будете отправлены на исходный файл для hủy bỏ.h, который содержит полезные макросы для выхода из скриптов, если обнаружены ненормальные условия. Исходный код для помощников, которые мы использовали в этой главе, можно найти в директории src/Applications/helper. Не стесняйтесь рыться в дереве директорий, чтобы понять, что где и разобраться в стиле программ ns‑3.

Nguồn: www.habr.com

Thêm một lời nhận xét