Trabalho Final de Comunicação de Dados |
Prof.: Eduardo Parente Ribeiro |
Aluno: Juliano João Bazzo |
O NS (Network Simulator) é um simulador desenvolvido pela University College of Berkely. NS simula eventos discretos com o objetivo centrado em pesquisas em redes de comunicação de dados. Ele fornece um suporte substancial para simulações de protocolos da pilha TCP/IP, roteamento e protocolos multicast.
O simulador funciona baseado em scripts Tcl, porém seu núcleo foi desenvolvido em C++ e grande parcela dos módulos de suporte a tecnologias mais específicas em Otcl - versão orientada a objetos da linguagem Tcl. O seu núcleo pode ser modificado, ou personalizado, de acordo com as necessidades de cada usuário.
Atualmente o NS já é um software confiável, porém está em constante atualização graças aos desenvolvedores e aos usuários que descobrem os bugs para que possam ser corrigidos nas versões seguintes. O software está disponível para os sistemas operacionais Linux, Windows e outros sistemas baseados em Unix e pode ser baixado através do seguinte endereço http://www.isi.edu/nsnam/ns/index.html.
Neste mini tutorial o leitor poderá encontrar uma breve introdução sobre a linguagem TCL e OTCL em seguida exemplos de simulações para serem executadas no NS e finalmente técnicas para a implementação de novos protocolos de roteamento.
Exemplo 1: Criação de uma de um script em TCL que faz diversos cálculos matemáticos simples e mostra o resultado na tela.
############################## # Exemplo 1 # ############################## proc teste {} { #Atribui os valores as variárveis set a 10.0 set b 5 #mostra o valor de a puts $a # A variável possui o seguinte resultado: c =(a+b)* b set c [expr [expr $a + $b] * $b] for {set k 0} {$k<10} {incr k} { if {$k<5} { puts [expr $k * $c] } else { puts [expr $k / $c] } } } #Chama o procedimento teste{} testeO próximo exemplo é um programa em TCL Orientado à Objeto ou OTCL. Este exemplo é muito simples, mas mostra a forma com que os objetos são criados e usados no OTCL. Como um usuário normal do NS, as mudanças que fará em seus objetos serão raras. No entanto, como os scripts e simulação do NS são escritos em OTCL, é importante um entendimento desta forma de programação.
Exemplo 2: Criação de um script OTCL que possui 2 classes "Mae" e "Filha" sendo que a classe "Filha" herda as variáveis da classe "Mae".
# Cria uma classe "Mae" e um # método "cumprimento" Class Mae Mae instproc cumprimento {} { $self instvar idade_ puts "Mae com $idade_ anos de idade diz: Oi, tudo bem?" } # Cria uma classe "Filha", que herda as # variáveis da classe "Mãe", e um método # "cumprimento" Class Filha -superclass Mae Filha instproc cumprimento {} { $self instvar idade_ puts "Filha com $idade_ anos de idade diz: Oi, tudo certinho?" } # Cria um objeto da classe Mae e Filha e # atribui a idade a elas. set a [new Mae] $a set idade_ 45 set b [new Filha] $b set idade_ 15 # Chama o método cumprimento de cada classe $a cumprimento $b cumprimento
#Cria o objeto simulador set ns [new Simulator] #Cria o arquivo de trace para o nam set nf [open out.nam w] #Define que toda a simulação será registrada no out.nam $ns namtrace-all $nf #Define o procedimento de encerramento que fecha o simulador e abre o nam proc finish {} { global ns nf $ns flush-trace #Fecha o trace file close $nf #Executa nam com o trace file exec nam out.nam & exit 0 } #Cria dois nós. A definição da configuração do nó é a padrão set n0 [$ns node] set n1 [$ns node] #Cria um link duplex entre eles, com largura de banda de 1Mbps e delay de 10ms $ns duplex-link $n0 $n1 1Mb 10ms DropTail #Chama o procedimento finish após 10 segundos de simulação $ns at 10.0 "finish"A saída no NAM é a seguinte:
O link entre os roteadores r1 e r2, chamada rota "vermelha" pode tratar
uma fila de até 25 pacotes. O gráfico seguinte ao código
mostra o tamanho e tamanho médio da fila.
O gráfico de saída foi obtido através do pacote
xgraph que está disponível na maioria dos kernels linux atualmente.
set nf [open out.nam w] #Define que toda a simulação será registrada no out.nam $ns namtrace-all $nf #Define o procedimento de encerramento que fecha o simulador e abre o nam proc finish {} { global ns nf $ns flush-trace #Fecha o trace file close $nf #Executa nam com o trace file exec nam out.nam & exit 0 } #Cria três nós. A definição da configuração do Nó é a padrão set n0 [$ns node] set n1 [$ns node] set n2 [$ns node] #Cria um agente CBR(Constant Bit Reate) e vincula ao nó n0 set cbr0 [new Agent/CBR] $ns attach-agent $n0 $cbr0 #Seta o tamanho do pacote e o intervalo de envio $cbr0 set packetSize_ 500 $cbr0 set interval_ 0.005 #Cria um agente Null para sincronização de tráfego e vincula ao nodo n1 set null0 [new Agent/Null] $ns attach-agent $n1 $null0 #Conecta os agentes para estabelecer a comunicação $ns connect $cbr0 $null0 #Faz o schedule dos eventos do agente CBR $ns at 0.5 "$cbr0 start" $ns at 4.5 "$cbr0 stop" #Cria um link duplex entre eles, com largura de bandas de 2Mbps/1Mbps e #delay de 5ms/10ms respectivamente $ns duplex-link $n2 $n1 2Mb 5ms DropTail $ns duplex-link $n0 $n1 1Mb 10ms DropTail #Chama o procedimento finish após 10 segundos de simulação $ns at 10.0 "finish" #Executa a simulação $ns runA saída no NAM é a Seguinte
set ns [new Simulator] #Cria o arquivo de trace para o nam set nf [open out.nam w] #Define que toda a simulação será registrada no out.nam $ns namtrace-all $nf #Define o procedimento de encerramento que fecha o #simulador e abre o nam proc finish {} { global ns nf $ns flush-trace #Fecha o trace file close $nf #Executa nam com o trace file exec nam out.nam & exit 0 } #Cria 4 nós set n0 [$ns node] set n1 [$ns node] set n2 [$ns node] set n3 [$ns node] #Cria um agente CBR (Constant Bit Reate) set cbr0 [new Agent/CBR] set cbr1 [new Agent/CBR] $ns attach-agent $n0 $cbr0 $ns attach-agent $n1 $cbr1 #Seta o tamanho do pacote e o intervalo de envio $cbr0 set packetSize_ 500 $cbr0 set interval_ 0.005 $cbr1 set packetSize_ 500 $cbr1 set interval_ 0.01 #Cria um agente Null para sincronização de tráfego e vincula ao nodo n1 set null0 [new Agent/Null] ns attach-agent $n3 $null0 #Conecta os agentes para estabelecer a comunicação $ns connect $cbr0 $null0 $ns connect $cbr1 $null0 # Identificação do fluxo de pacotes # O parametro 'fid_' significa 'flow id'. $cbr0 set fid_ 1 $cbr1 set fid_ 2 #Setando a cor dos pacotes $ns color 1 Blue $ns color 2 Red #Faz o schedule dos eventos do agente CBR $ns at 0.5 "$cbr0 start" $ns at 10.5 "$cbr0 stop" $ns at 0.0 "$cbr1 start" $ns at 12.0 "$cbr1 stop" #Setar a orientação entre ele, note que o link n3-n2 é um "gargalo na rede" $ns duplex-link $n0 $n2 10Mb 10ms DropTail $ns duplex-link $n1 $n2 10Mb 10ms DropTail $ns duplex-link $n3 $n2 1Mb 10ms DropTail #Chama o procedimento finish apos 5 segundos #de simulação $ns at 13.0 "finish" #Executa a simulação $ns runA saída no NAM é a Seguinte
set ns [new Simulator] set nf [open out.nam w] $ns namtrace-all $nf proc finish {} { global ns nf $ns flush-trace #Fecha o trace file close $nf #Executa nam com o trace file exec nam out.nam & exit 0 } #Cria 5 nós set n0 [$ns node] set n1 [$ns node] set n2 [$ns node] set n3 [$ns node] set n4 [$ns node] #Cria um agente CBR (Constant Bit Reate) set cbr0 [new Agent/CBR] set cbr1 [new Agent/CBR] $ns attach-agent $n0 $cbr0 $ns attach-agent $n1 $cbr1 #Seta o tamanho do pacote e o intervalo de envio $cbr1 set packetSize_ 500 $cbr1 set interval_ 0.01 #Cria um agente Null para sincronização de tráfego #o e vincula ao nodo n1 set null0 [new Agent/Null] ns attach-agent $n3 $null0 #Conecta os agentes para estabelecer a comunicação $ns connect $cbr0 $null0 $ns connect $cbr1 $null0 # Identificação do fluxo de pacotes # O parametro 'fid_' significa 'flow id'. $cbr0 set fid_ 1 $cbr1 set fid_ 2 #Setando a cor dos pacotes $ns color 1 Blue $ns color 2 Red #Faz o schedule dos eventos do agente CBR $ns at 0.5 "$cbr0 start" $ns at 10.5 "$cbr0 stop" $ns at 0.0 "$cbr1 start" $ns at 12.0 "$cbr1 stop" #Setar a orientação entre ele $ns duplex-link $n0 $n2 1Mb 10ms DropTail $ns duplex-link $n1 $n2 1Mb 10ms DropTail $ns duplex-link $n3 $n2 10Mb 10ms DropTail $ns duplex-link $n0 $n4 1Mb 10ms DropTail $ns duplex-link $n4 $n3 1Mb 10ms DropTail #Re-roteamento $ns rtmodel-at 3.0 down $n2 $n3 $ns rtmodel-at 8.0 up $n2 $n3 # Seta o protocolo de roteamento alternativo $ns rtproto DV #Chama o procedimento finish apos 13 segundos $ns at 13.0 "finish" #Executa a simulação $ns runA saída no NAM é a Seguinte
set ns [new Simulator] set nf [open out.nam w] $ns namtrace-all $nf proc finish {} { global ns nf $ns flush-trace #Fecha o trace file close $nf #Executa nam com o trace file exec nam out.nam & exit 0 } #Cria 7 nós set n0 [$ns node] set n1 [$ns node] set n2 [$ns node] set n3 [$ns node] set n4 [$ns node] set n5 [$ns node] set n6 [$ns node] #Atribui os agentes set cbr0 [new Agent/CBR] set cbr1 [new Agent/CBR] set tcp2 [new Agent/TCP] set exp5 [new Application/Traffic/Exponential] set udp5 [new Agent/UDP] $ns attach-agent $n0 $cbr0 $ns attach-agent $n1 $cbr1 $ns attach-agent $n2 $tcp2 $ns attach-agent $n5 $udp5 #Seta o tamanho do pacote e o intervalo de envio $cbr1 set packetSize_ 500 $cbr1 set interval_ 0.01 set size 1500 set burst 5s set idle 2s set rate 10M $exp5 set packet-size $size $exp5 set burst-time $burst $exp5 set idle-time $idle $exp5 set rate $rate $exp5 attach-agent $udp5 #Cria um agente Null , para sincronização de tráfeg #o e vincula ao nodo n1 set null0 [new Agent/Null] $ns attach-agent $n3 $null0 set sink [new Agent/TCPSink] $ns attach-agent $n6 $sink #Conecta os agentes para estabelecer a comunicação $ns connect $cbr0 $null0 $ns connect $cbr1 $null0 $ns connect $tcp2 $sink $ns connect $udp5 $null0 set ftp [new Application/FTP] $ftp attach-agent $tcp2 # Identificação do fluxo de pacotes # O parametro 'fid_' significa 'flow id'. $cbr0 set fid_ 1 $cbr1 set fid_ 2 $ftp set fid_ 3 $udp5 set fid_ 4 #Setando a cor dos pacotes $ns color 1 Blue $ns color 2 Red $ns color 3 Black $ns color 4 White #Faz o schedule dos eventos do agente $ns at 0.0 "$ftp start" $ns at 11.5 "$ftp stop" $ns at 0.5 "$cbr0 start" $ns at 12.0 "$cbr0 stop" $ns at 0.8 "$cbr1 start" $ns at 12.0 "$cbr1 stop" $ns at 0.0 "$exp5 start" $ns at 10.5 "$exp5 stop" #Setar a orientação entre ele $ns duplex-link $n0 $n2 1Mb 10ms DropTail $ns duplex-link $n1 $n2 1Mb 10ms DropTail $ns duplex-link $n3 $n2 1Mb 10ms DropTail $ns duplex-link $n0 $n4 1Mb 10ms DropTail $ns duplex-link $n4 $n5 1Mb 10ms DropTail $ns duplex-link $n5 $n3 1Mb 10ms DropTail $ns duplex-link $n1 $n5 1Mb 10ms DropTail $ns duplex-link $n4 $n6 1Mb 10ms DropTail #Re-roteamento $ns rtmodel-at 1.5 down $n2 $n3 $ns rtmodel-at 4.0 up $n2 $n3 # Seta o protocolo de roteamento alternativo $ns rtproto DV #Chama o procedimento finish apos 13 segundos #de simulação $ns at 13.0 "finish" #Executa a simulação $ns runA saída no NAM é a Seguinte
- Addr_:
Endereço do Nodo de origem
- Dst_:
Para onde os pacotes estão sendo enviados
- Size_:
Tamanho do pacote em bytes
- Type_:
Tipo de pacote
- Prio_:
O campo IP de prioridade
- Flags
_: os flags do pacote
- Defttl_:
O valor default do ttl
Essas variáveis podem ser modificadas em qualquer classe derivada
da classe Agente.
Packet* allocpkt(): Aloca um novo pacote e assinala seus campos. Esta função preenche os seguintes campos em um tipo de pacote normal: uid, ptype, size e os seguintes campos do cabeçalho IP: src,dst,plowid,prio,ttl. E também completa de zeros os seguintes Flags do cabeçalho: ecn,pri,usr1,usr2. Qualquer informação extra no pacote deve ser tratada nas funções derivadas da classe Agente.
Packet* allocpkt(int):Aloca um novo pacote com o "data payload" de n bytes e assinala seus campos.
As funções a seguir também são definidas na classe Agente, mas devem ser sobrescritas pelas classes que derivam Agente:
Void timeout(timeout number):Função de controle do timeout
Void recv(Packet*, Handler *): Função principal que controla a recepção de pacotes do Agente. Este função é o ponto de entrada na recepção de pacotes e é invocada pelos outros nós quando enviam um pacote. Na maioria dos casos os Agentes não fazem uso do segundo argumento(este é o handler do pacote que está enviando o pacote).
A instrução new Agente/TCP resulta na criação do objeto C++TcpAgent. Seu construtor invoca primeiro o construtor da classe base Agente e depois efetua seus proprios bindings.
O Agente TcpAgent é inicializado nesse exemplo quando o FTP recebe a diretiva start no tempo 1.2 segundos. A operação start é definida em ~ns/tcl/lib.ns-source.tcl
Application/FTP
instproc start{}{
[$self
agente] send –1
}
Neste caso a variável agente está vinculada ao agente
TCP e send –1 é analogo a enviar um arquivo extremamente grande.
A chamada send faz com que o agente TCP comece a enviar pacotes.
Neste caso a função output do Agente TCP efetua as seguintes
chamadas:
void TcpAgent::output(int seqno, int reason) { &nbs p; Packet * p= allocpkt(); hdr_tcp * tcph = (hdr_tcp*) p->access(off_tcp); double now = Scheduler::instance().clock(); tcph->seqno = seqno; tcph->ts() = now; Connector::send(p,0); ... }Esta rotina primeiro aloca um novo pacote (com seus cabeçalhos e os cabeçalhos IP preenchidos) e depois preenche os campos especificos para o Agente. Para encontrar o cabeçalho TCP no pacote a variavel off_tcp_ deve estar apropriadamente inicializada. O método access da classe Packet retorna o respectivo cabeçalho, o qual é preenchido e o send da classe Conector é chamado para enviar o pacote. O operador de escopo :: do C++ foi utilizado para evitar chamar a função send do Agente.
No agente que está recebendo os pacotes a entrada é processada através das funções recv() e ack().
3. Base de Dados de Scripts de Simulação
4. Tutorial da UFMG (Autor:Ricardo Rabelo)