Estrutura dos quadros da camada de Enlace de Dados

Como já vimos no artigo anterior, a camada de enlace de dados trabalha com quadros. Neste artigo veremos como é a estrutura deles.

***

Contagem de Caracteres


Quando tudo começou, a primeira idéia foi, claro, bem simples. E para entendê-la, imaginemos que a camada de enlace de dados tenha que transmitir a seguinte frase: "O blog Vovó Viu a Rede é bom demais".

Visando garantir que os quadros tivessem tamanhos variados, o primeiro byte de quadro tinha um número que indicava o seu comprimento. Imaginando que cada quadro vá transmitir uma palavra da nossa frase de exemplo, junto com o espaço da direita, os dados seriam transmitidos assim (reparem que os números levam em consideração os espaços):

2O 5blog 5Vovó 4Viu 2a 5Rede 2é 4bom 6demais


Fica claro pra qualquer um que as chances de isso dar errado são altíssimas: basta um número errado para que uma seqüência de pacotes seja perdida. Imagine que o primeiro número, o 2, virasse um 6. A camada de enlace de dados receptora veria este número seis e receberia os 6 próximos bytes: "O 5blo". Bela palavra, não?

Mas o pior vinha em seguida: sabendo que suposto quadro de quatro bytes tinha terminado, a camada de enlace de dados pegaria o próximo número para saber o tamanho do próximo quadro. E qual seria o número recebido?

g


Aí é que a porca torce o rabo, pois 'g' não é um número, logo a camada de enlace de dados não tem como continuar e manda um aviso de volta, acusando a falha.

A bagunça pode ser pior ainda se a informação a ser transmitida forem números: um quadro fica com tamanho errado, a camada de enlace de dados lê até o byte errado, pega o próximo, que também é um número, acha que ele é um indicador de tamanho e segue em frente. Sentiu o drama?

Outro problema trazido por esta situação era que a camada de enlace de dados não tinha como saber onde o quadro acabava. Ela apenas sabia onde ele começava, e só sabia isso se estivesse tudo sem erros.

Na época em que este método foi criado a camada física não era tão confiável como é hoje em dia, com as fibras óticas e afins, por isso a quantidade de erros gerados era enorme. Logo logo as cabeças pensantes arranjaram um jeito de contornar isso.

***

Bytes de Flags


A solução encontrada para o problema que acabamos de ver se deu por meio da inserção de bytes especiais no início e no fim de cada quadro, para servir de moldura.

Digamos que para o nosso exemplo escolhêssemos a letra 'f' para servir de flag. Ainda com a idéia de que cada quadro carregue uma palavra, a transmissão seria esta:

fO ffblog ffVovó ffViu ffa ffRede ffé ffbom ffdemaisf


Fazendo assim a transmissão fica um pouco mais confiável porque um quadro corrompido não inutiliza toda a transmissão. Basta procurar o próximo par de bytes de flag para saber onde o próximo quadro começa. Veja só:

Imagine que o byte de flag que fecha o primeiro quadro se corrompa e se transforme em um 'g'. Para a camada de enlace de dados receptora, o primeiro quadro seria, então, este:

O g


O que aconteceu? A camada enlace de dados pensou que o byte que abre o segundo quadro fosse o byte que fecha o primeiro. Daí, ao procurar um byte de abertura, ela daria de cara com o 'b' da palavra "blog", veria que ele não é um byte de flag, e logo saberia que alguma coisa deu errada

Daí ela iria desconsiderar tudo o que viesse em seguida até achar um par de bytes de flag, e encontraria os "ff" antes da palavra "Vovó ". Deste modo, ela saberia que ali estava um quadro correto, e seguiria em frente.

Só que isso traz um novo problema: se o método funciona bem com a nossa frase de exemplo, imagine como seria a transmissão da palavra "fofura":

ffofuraf


Eita que sobrou foi 'f' nisso aí!

A camada de enlace de dados receptora iria trabalhar assim: o primeiro 'f' começa um quadro, o segundo 'f' termina um quadro. Ih, é um quadro vazio. Tem que vir outro 'f' para começar um novo, mas vem um 'o'. Descarta. Procura um par de 'f', não tem. E lá se foi todo o pacote. Perdemos a palavra. Problema sério, não?

Já pensando nisso, os idealizadores desta solução pensaram no seguinte: colocar um outro caractere de aviso para informar que o caractere que vem depois dele é pra ser lido como parte do pacote, e não como um caractere especial. Para nosso exemplo, vamos usar a letra 'n' como caractere de aviso. A palavra "fofura" seria transmitida assim:

fnfonfuraf


(Ufa, ainda bem que temos computadores para entender essa bagunça!)

A camada de enlace de dados receptora iria trabalhar nesta mensagem da seguinte maneira (leia devagar para não confundir): o primeiro 'f' começa um quadro; daí vem um 'n', logo ela sabe que o que vem depois não é um byte de flag; daí vem o 'f', que é lido, depois o 'o', e por aí vai, até chegar ao último 'f', que, por não ter um 'n' antes, é interpretado como um "fim de quadro". E, assim, a palavra "fofura" é recebida corretamente.

Mas ainda havia um problema: e se a palavra a ser transmitida fosse "ninfa"? O quadro seria este:

fninnfaf


Repare bem: ali estão os 'f' que abrem e fecham o quadro mais o 'n' antes do 'f' que não é flag.

A interpretação da mensagem seria esta (novamente leia devagar para não confundir): o primeiro 'f' abre o quadro; depois vem o 'n', que é interpretado como aviso, dizendo que o que vem depois é pra ser lido como parte do quadro; e vem o 'i', que é lido; depois outro 'n', interpretado como aviso; depois outro 'n', o que era para ser um aviso, mas será interpretado como parte do quadro; depois vem o 'f', que por não ter nada antes é interpretado como 'fim de quadro'. Daí pra frente nada é lido, e a palavra que chega é "in". Feio, né?

A solução inventada para este problema é a mesma de antes: colocar o caractere de aviso antes de um caractere de aviso falso! Deste jeito a palavra "ninfa" seria transmitida assim:

fnninnnfaf


Vou até separar por linhas a interpretação disso para ficar mais fácil de entender:

'f': indica início de quadro
'n': indica que o que vem depois é parte do quadro
'n': lido normalmente
'i': lido normalmente
'n': indica que o que vem depois é parte do quadro
'n': lido normalmente
'n': indica que o que vem depois é parte do quadro
'f': lido normalmente
'a': lido normalmente
'f': indica fim de quadro

O que foi lido normalmente? "ninfa".

***


Pois bem, depois destes novo método, mais outros foram criados. Um deles é a inserção de bits de flag, ao invés de bytes de flag. Uma das vantagens disso é a economia de recursos, pois o gasto de banda usada apenas para as flags diminui em 8 vezes (pois cai de 8 bits para apenas 1). Fazendo as contas em larga escala, vê-se que a economia é gigantesca.

Há também métodos que usam as características da camada física, mas aí a coisa já fica muito específica pra demais da conta e sai do foco do blog e dos meus estudos, por isso vou passar longe disso.

Hoje em dia, visando proporcionar mais segurança na transmissão, muitos protocolos da camada de enlace de dados utilizam métodos que mesclam estas técnicas que vimos neste artigo. Por exemplo: quadros que têm flags marcando seus limites e também indicadores de tamanho. Ao receber um quadro, a camada de enlace de dados vê o tamanho dele e verifica se entre as flags de início e fim há aquele número de caracteres informado. Se não houver, o quadro é dado como errado.

***


Links interessantes:
  • Veja aqui o que já foi publicado no Vovó Viu a Rede sobre a camada de enlace de dados.

  • 5 comentários:

    Anônimo disse...

    foi interessante só que com uma linguagem não tecnica...

    Mário Marinato disse...

    Que bom que gostou, anônimo.

    A linguagem não-técnica é o que busco ao escrever.

    Unknown disse...

    Simplesmente perfeito, seria impossível alguem não enteder.
    Está de PARABÉNS estou estudando para uma prova e o blog me ajudou muito e linguagem técnica se encontra muito nos livros que parecem mais complicar do que se fazer entender.

    Mário Marinato disse...

    Valeu pelo elogio, Victor.

    É bom saber que estou agradando e que, principalmente, estou ajudando vocês com seus estudos.

    Grande abraço.

    Anônimo disse...

    Por que então o PPP utiliza byte stuffing ao invés de bit stuffing? =T