O objetivo deste laboratório é melhorar suas
habilidades de depuração e de teste. O laboratório
requer que você construa classes para um aplicativo existente e
trate adequadamente situações de erro e
exceção.
O NodeNet é um simulador de roteamento em redes. Nele
você pode desenhar uma rede composta de vários nós
que geram, roteiam e consomem nós. Na prática, os
nós poderiam ser, por exemplo, computadores conectados pela
internet, enviando e recebendo dados. Para ver o simulador executando,
digite: java -jar nodenet.jar. Na barra à esquerda
aparecerão três tipos de nós: "Generator",
"Intermediate" e "Terminator". À direita está o
espaço onde uma rede pode ser criada e simulada. Para criar uma
rede clique sobre um tipo de nó e, em seguida, clique na
área de simulação para criar nós do tipo
escolhido. Para formar uma rede, os nós devem ser
interconectados por "canais". Para criar um canal faça um duplo
clique sobre o nó de origem e, em seguida, um clique simples no
nó de destino. A aplicação tem três menus:
"File", "Simulation" e "Selection". Os comandos disponíveis
são bastante intuitivos para serem entendidos com o uso.
Antes de começar a programar, faça algumas
simulações com os nós existentes. Observe o
comportamento e entenda o funcionamento dos nós. Crie algumas
topologias de rede e grave-as (como templates) em um diretório
compartilhado por todos da turma, de forma que se crie um
repositório de topologias que poderão ser usadas para
testar o comportamento das classes que vocês irão
descrever. Dê nomes significativos às topologias. Mude o
nó intermediário default da aplicação,
digitando:
java -cp nodenet.jar nodenet.Main nodenet.DefaultNodeBehavior
Compare o comportamento desse nó com o intermediate. Observe
que quando você lê uma topologia, são usados os
nós que tiverem sido lidos pela aplicação. Eles
são usados na ordem em que estiverem na coluna à esquerda
(para mudar clique com o botão direito do mous). Descreva as
diferenças entre as duas classes de nós
intermediários.
Veja que cada nó e cada canal pode ser configurado (selecione
o objeto e escolha o comando "Configure" no menu Selection). Veja o
efeito disso sobre a simulação. Perceba que durante a
simulação você pode desabilitar e habilitar
novamente os nós e os canais. Remoções e
adições de nós e canais, contudo, não devem
ser feitas durante as simulações.
Os números nos nós Generator e Terminator durante uma
simulação indicam o número de pacotes gerados e
consumidos, respectivamente. Além disso, o número de
"bolinhas" em cada canal indica o número de pacotes que trafegam
por ali naquele instante. Quando o canal fica cheio ele muda de cor
para vermelho. Tente fazer simulações em que os canais
fiquem cheios. O que ocorre com os pacotes nessa situação?
Seu objetivo é escrever o código necessário
para descrever o comportamento de um nó intermediário (um
nó corretamente implementado não deverá perder ou
criar pacotes). Para isso você deve criar uma classe que
implemente a interface "NodeBehavior".
Embora os nós implementem Runnable, suas classes não
precisam ser. Na prática, os nós têm sua
própria Thread, mas eles repassam a responsabilidade para
determinar o comportamento para um objeto do tipo NodeBehavior. O
nó também faz todo o tratamento gráfico
necessário, logo sua classe só deve tratar
especificamente com a questão lógica do comportamento do
nó. Quando você tiver feito a classe, leia-a do NodeNet
para usá-la em simulações e experimentá-la.
O método run() do nó é essencialmente o
seguinte:
public void run( ) {
while( true ) {
this.nodeBehavior.transmitPacket( this.inputChannels, this.outputChannels );
}
}
Veja que transmitPacket() recebe dois argumentos: inputChannels e
outputChannels. O primeiro é do tipo InputChannelVector
e o segundo do tipo OutputChannelVector.
Cada um deles corresponde a um vetor de objetos do tipo InputChannel e
OutputChannel,
respectivamente. O comportamento de um nó a cada ciclo (o que
você deve escrever) consiste em ler um objeto de um dos canais de
entrada e escrevê-lo em um dos canais de saída. Embora
pareça simples, lembre que há múltiplos canais de
entrada e de saída e que eles podem estar habilitados ou
desabilitados e que eles podem estar vazios (os de entrada) ou cheios
(os de saída). Todas essas condições devem ser
adequadamente tratadas.
Há diversas estratégias que você pode adotar
para decidir quais canais usar a cada ciclo. Pense em pelo menos duas e
implemente-as. Leia atentamente a documentação das
classes envolvidas. Experimente sua classe com diversas
simulações. Use as topologias disponibilizadas pelos
outros usuários. Isso irá submeter sua classe a
situações que você não previu, de forma
semelhante como código real é submetido a
condições inesperadas quando colocado em
produção. Para facilitar a execução de suas
classes use a seguinte linha para executar o NodeNet, incluindo o
diretório em que sua classe está como parte do classpath:
java -cp /caminho/do/nodenet.jar:/caminho/de/sua/classe/ nodenet.Main