Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ММТССиПД_ns2_метода

.pdf
Скачиваний:
107
Добавлен:
15.03.2015
Размер:
1.02 Mб
Скачать

set y second;

set x $myArray($y);

Здесь проиллюстрировано использование подстановки переменных в пределах круглых скобок, задающих индекс массива.

Вторая форма подстановки переменных имеет место, когда за знаком доллара следует левая изогнутая скобка. В этом случае имя переменной состоит из всех символов до соответствующей закрывающей изогнутой скобки. Необходимо отметить, что в этом случае переменная должна являться скаляром, но не массивом. Пусть переменная x имеет значение n. Тогда

команда:

set y ${x}s2

является эквивалентным команде:

set y ns2

Подстановка переменных не происходит в параметрах, которые включены в изогнутые скобки.

Знак доллара является просто сокращением общей формы [set var].

Так, например, запись $var является сокращенной формой [set var].

Обычно, каждая команда занимает одну строку и заканчивается символом новой строки. Символ точка с запятой (";") позволяет размещать на одной строке несколько команд. Точки с запятой не обрабатываются как разделители команд, если они появляются в пределах изогнутых скобок или двойных кавычек.

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

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

\b – Возврат на один символ (0x8),

\f – Перевод страницы (0xc),

\n – Новая строка (0xa),

23

\r – Перевод каретки (0xd),

\t – Табуляция,

\v – Вертикальная табуляция,

\{ – Левая изогнутая скобка ("{"),

\} – Правая изогнутая скобка ("}"),

\[ – Левая квадратная скобка ("["),

\] – Правая квадратная скобка ("]"),

\$ – Знак доллара ("$"),

\sp – Пробел (" "),

\; – Точка с запятой, не ограничивает команду,

\" – Двойная кавычка,

\nl – Присоединяет следующую строку к данной,

\\ – Обратный слеш ("\"),

\ddd – Восмиричное представление числа ddd.

Примеры:

set x \{Code\} Переменная x будет установлена в {Code}. set x \[set y 10\] Переменная x будет установлена в [set

y10]

set x My\tname\tis Переменная x будет установлена в My

name is

Обратный слеш, за которым следуют символы, отличные от перечисленных выше, интерпретируется Tcl как обычная косая черта ("\").

set x \Bonch

Переменная x будет установлена в \Bonch.

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

24

скобки не означают поиска соответствующей парной скобки, заканчивающей аргумент. Например, в команде:

set a {\{abc}

второй аргумент команды set будет \{abc.

Последовательности с обратным слешем не достаточны для генерации любой структуры поля параметра и учитывает лишь наиболее общие случаи.

В тех случаях, когда последовательностей с обратным слешем недостаточно,

необходимо использовать команду format вместе с подстановкой команд и переменных.

Выражения Tcl

Выражения являются неотъемлемой составляющей любого языка программирования. Несколько Tcl-команд, таких как expr, for или if,

обрабатывают один или большее количество параметров как выражения и вызывают обработчики выражений Tcl (Tcl_ExprLong,

Tcl_ExprBoolean, и т.д.) для их оценки. Операторы, разрешенные в выражениях Tcl – подмножество операторов, разрешенных в выражениях C, и

они имеют то же самое значение и старшинство как соответствующие операторы C. Выражения почти всегда выдают числовые результаты (целое число или значения с плавающей точкой). Так, например, выражение

8.2 + 6

будет равно 14.2. Выражения Tcl отличаются от выражений C методами определения. Кроме того выражения Tcl поддерживают нечисловые операнды и сравнения строк.

Выражения Tcl состоят из комбинации операндов, операторов и круглых скобок. Пробельные символы и символы табуляции при анализе выражений игнорируются. Там, где это возможно операнды интерпретируются как целочисленные значения. Целочисленные значения могут быть определены в десятичном, восьмеричном (если первый символ операнда – "0"), или в шестнадцатеричном виде (если первые два символа операнда – "0x"). Если операнд не принадлежит ни к одному из

25

целочисленных форматов, приведенных выше, то он будет обработан как число с плавающей запятой (если это возможно). Числа с плавающей запятой могут быть определены аналогично стандартному ANSI C. Исключение составляет запрет в большинстве версий на суффиксы f, F, l и L. Например,

все следующие записи идентичны: 2.0, 2., 2e1, 2.0e+1.

Операнды могут быть определены одним из следующих способов:

как числовое значение, или целое число или число с плавающей

точкой;

как переменная Tcl, используя "$" или [set variable].

Значение переменной используется как операнд;

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

как строка, включенная в изогнутые скобки. Символы между скобками используются как операнд без предварительных подстановок;

как команда Tcl, заключенная в квадратные скобки. Команда предварительно выполняется, и ее результат далее используется как операнд.

В тех случаях, когда подстановки происходят в соответствии с вышеперечисленными случаями, они выполняются процессором выражений.

Но дополнительный уровень подстановки, может быть осуществлен анализатором команд.

Предположим, что переменная x имеет значение 3, переменная y имеет значение 6. Рассмотрим несколько примеров:

3.1 + $x (6.1)

2 + "$x.$y" (5.6)

4 * [llength " 6 2 "] (8) {word one} < “ word $x” 0

Списки Tcl

Третьей основной смысловой формой строк в Tcl являются списки.

Список – это обычная строка с подобной списку структурой, состоящей из

26

полей, разделенных промежутками. Например, строка State University of Telecommunications есть список, имеющий четыре элемента (поля). Основная структура списков аналогична структуре командных строк, за исключением того, что символ новой строки служит таким же разделителем, как и пробел с табуляцией. Для списков действуют такие же правила в отношении фигурных скобок, двойных кавычек и обратных слешей, как и для команд. Например,

строка:

a b\ с {d e {f g h} }

есть список из трех элементов: a, b с и d e {f g h}. Всегда, когда из списка извлекается элемент, действуют те же правила относительно фигурных скобок, двойных кавычек и обратных слешей, что и для команд. Таким образом, когда из списка в примере будет извлечен третий элемент, результат будет d e {f g h} (потому что при извлечении произошло только отбрасывание внешней пары фигурных скобок). В отношении списков никогда не выполняются подстановки команд и переменных (по крайней мере,

командами обработки списков: список всегда может быть передан интерпретатору Tcl для обработки).

Команды Tcl concat, foreach, lappend, lindex, linsert, list, llength, lrange, lreplace, lsearch и lsort позволяют составлять списки, извлекать из них элементы, просматривать содержимое и выполнять прочие относящиеся к спискам функции.

Более подробно описание языка Tcl можно найти в [1], [2] и [3].

3.2.2. ЯЗЫК OTCL

Язык OTcl является объектно-ориентированным расширением языка

Tcl. Пользователю, достаточно свободно ориентирующемуся в C++,

синтаксис OTcl и программирование в OTcl не покажется достаточно сложным. Так как C++ является на сегодняшний день наиболее распространенным объектно-ориентированным языком программирования,

вначале коротко перечислены основные различия между OTcl и C++:

27

Каждое определение метода в OTcl (с использованием instproc)

добавляет метод к классу. Каждое определение переменной (при помощи set

или через instvar в теле метода) добавляет переменную к объекту;

Вместо конструктора, используемого в C++ необходимо определять instproc init в OTcl. Вместо деструктора в C++, определяется destroy instproc в OTcl. В отличие от конструкторов и деструкторов, методы init

и destroy, не объединяются с базовыми классами автоматически. Они должны быть объединены явно с использованием next.

В отличие от C++, методы в OTcl всегда вызываются через объекты;

Self в OTcl эквивалентно this в C++ и может использоваться внутри метода. В отличие от C++, методы OTcl всегда виртуальны;

Вместо вызова скрытых методов посредством указания их имени как в

C++, необходимо использовать next. next сканирует диаграмму наследственности, и находит скрытые методы автоматически. Это позволяет объединять методы без именных зависимостей;

Необходимо избегать использования статических методов и переменных, так как в OTcl не существует их полных аналогов. Ввод общих переменных на объекте класса и обращение к ним из методов происходит при использовании $class.

Если наследственность не необходима, используется proc методы на объекте класса.

Создание класса myClass происходит с помощью следующих строк:

% Class myClass

myClass

Теперь можно создавать реализации класса myClass. Используя info

можно получить информацию о классе и его реализациях:

%myClass instance1 abagel

%instance1 info class myClass

%myClass info instances instance1

28

Данный класс, в принципе, ничего не делает – он просто существует. Но при помощи метода set возможно создать переменную экземпляра.

Необходимо отметить, что здесь все переменные являются public (если рассматривать C++). Метод info позволяет получить всю необходимую информацию. Так можно получить информацию об объявленных переменных, а также их значениях:

%instance1 set myVar 0

0

%instance1 info vars myVar

%instance set myVar

0

Часто пользователю необходимо предварительно инициализировать переменные, непосредственно перед их использованием. Так в C++

используются конструкторы. В OTcl необходимо использовать init instproc

для класса myClass. Вообще каждый раз, когда необходимо инициализировать объекты, следует определять init instproc для рассматриваемого класса.

Рассмотрим пример:

% myClass instproc init {args} { $self set myVar 0;

eval $self next $args

}

%myClass instance2 instance2

%instance2 info vars myVar

%instance2 set myVar

0

Переменная self имеет значение аналогичное this в C++. Пример уничтожения экземпляра класса и создания:

%myClass info instances instance1 instance2

%instance destroy

%myClass info instances instance2

%myClass instance1

29

instance1

Методы, определенные на классах для использования в последующих экземплярах называются instprocs. Они имеют список параметров и код подобно обычной процедуре Tcl (proc). Создание нового метода:

%Bagel instproc myMethod {} { $self instvar myVar;

incr myVar;

if {$myVar > 1} then {

put "Oops, i did it again :)";

}

returnl {}

}

%myClass info instprocs

init myMethod

Помимо элементарного манипулирования с переменной myVar

(инкремент, анализ) код демонстрирует метод instvar. Он используется для объявления экземпляра переменной, и определить их в локальной области метода. Переменной экземпляра myVar, определенная ранее командой set

теперь можно манипулировать в пределах метода myMethod при помощи локальной переменной myVar.

Теперь можно вызывать метод myMethod аналогично instproc info и destroy. Методы info и destroy определены OTcl и существуют для каждого класса. Таким образом, нет никаких отличий пользовательских методов от методов, определенных системой.

% instance1 myMethod

Для рассмотрения процедуры наследования в OTcl определяется новый класс inheritedClass, который наследует myClass.

% Class inheritedClass -superclass myClass

inheritedClass

%inheritedClass info superclass myClass

%inheritedClass info heritage myClass Object

Впримере продемонстрированы дополнительные возможности метода

info. Параметр superclass позволяет уточнить, что класс

30

inheritedClass унаследован от myClass, а класс myClass, в свою очередь наследуется от Object. Класс Object включает все основные характеристики класса, от которого наследуются по умолчанию новые классы

(Class newClass эквивалентно Class newClass -superclass

Object).

Синтаксис создания нового класса, с использованием "-superclass",

требует дополнительного пояснения. Следующие объявления являются эквивалентными для OTcl – все они создают класс inheritedClass наследуемый от myClass.

% Class inheritedClass inheritedClass

%SpreadableBagel superclass myClass

%Class creat inheritedClass inheritedClass

%inheritedClass superclass myClass

%Class inheritedClass -superclass myClass inheritedClass

Добавление еще одного параметра:

%myClass instproc nextVar {n} { $self set myVar1 $n

}

%inheritedClass instance1 -nextVar 150 instance1

%instance1 set myVar1

150

Добавление инициализации к классу inheritedClass.

% inheritedClass instproc init {args} { $self set array {};

eval $self next $args

}

% instance1 instproc settings {args} { $self instvar array;

set array [concat $array $args] return $array

}

31

Теперь необходимо обратиться к объяснению значения next в методе init. Next используется для вызова инициализации для класса myClass (от которого наследуется inheritedClass). Init instproc инициализирует переменную myVar. В свою очередь next класса myClass вызывает инициализационный метод init класса Object. init класса Object

принимает в качестве параметров имена двух методов и значения параметров.

Итак, в предыдущих подразделах были рассмотрены основные особенности языка Tcl и его объектно-ориентированного расширения OTcl, c

помощью которых создаются скрипты (описания) моделируемых сетей в ns2.

Далее необходимо более подробно разобрать структуру ns2.

3.3. Основные компоненты моделирования ns2

Основными компонентами моделирования ns2 являются планировщик событий, сетевые объекты и события (at-события и пакеты).

3.3.1 ПЛАНИРОВЩИК СОБЫТИЙ

Основой моделирования в ns2 является планировщик событий (event scheduler). Основные пользователи планировщика событий – компоненты сети, которые моделируют задержку на обработку пакетов или которым нужны таймеры. Создание события сетевым элементом показано на рисунке

3.4. В планируемое время обрабатывает событие тот сетевой объект, который его создает. Информационный канал между сетевыми объектами отличается от канала событий. Фактически же, пакеты передаются от одного объекта к другому, используя метод send(Packet* p) {target_->recv(p)}; для передатчика и метод recv(Packet*, Handler* h = 0) для приемника. Ns2 имеет два вида планировщиков событий: реального времени и модельного времени. Для планировщика модельного времени (non-real time) доступны три реализации:

список (list), «куча» (heap) («куча» в лексиконе программистов означает – область памяти, выделяемая программе для динамически размещаемых структур данных) и календарь (calendar). Они выполняют одни и те же

32