# Introdução à comunicação entre computadores e tecnologias de rede/A sub-camada de controle lógico de ligações (LLC)

A Sub-Camada de Controle Lógico de Ligações, também cohecida pela sigla inglesa LLC é responsável por preparar uma mensagem para enviá-la pelo fio (ou pelo ar no caso de transmissões sem fio). Para enviar um dado, é preciso antes realizar uma série de operações como o enquadramento, controle de fluxo e controle de erros. Vamos ver agora qual a importância destas operações e em quê elas consistem.

## O Enquadramento

Enquadrar significa particionar uma seqüência de bits em pedaços menores chamados de quadros. A forma exata do enquadramento depende do tipo de rede. A vantagem de dividir a mensagem em quadros é que isso ajuda a máquina transmissora e receptora a manterem uma sincronia, pois cada quadro possui um delimitador que mostra quando ele começa e quando termina.
Um tipo comum de enquadramento é usar uma seqüência de bits (como 01111110) como delimitador entre o começo e o fim de um quadro. Então, usando este tipo de delimitador, a mensagem passaria pela seguinte transformação:
Entretanto, no nosso exemplo, você deve notar que existe um pequeno problema: o que acontece se a mensagem que queremos enviar tem um padrão de bits igual ao que usamos para delimitar os quadros? Por exemplo, e se tivéssemos querendo enviar a mensagem "011111100011110" sendo que 01111110 é o nosso delimitador? No caso acima, uma possível solução seria colocar um sinal de "0" depois de cada seqüência de cinco "1"s seguidos. O nome que se dá ao processo de colocar bits a mais na mensagem para que ela não se confunda com o delimitador é preenchimento de bits. Vejamos um exemplo disso na prática:
Este tipo de quadro acima foi mostrado apenas com propósitos didáticos. Na prática não é assim que ocorre um enquadramento de verdade. Existem muitos padrões diferentes para quadros. Vamos dar uma olhada no quadro do padrão IEEE 802.3 apenas para termos um exemplo que é usado na vida real. As informações que vão em um quadro são:
* Preâmbulo (8 bytes): O preâmbulo é o que é usado como delimitador entre um quadro e outro. Ele é formado por 7 bytes idênticos com o valor "10101010" mais um último byte com o valor "10101011".
* Cabeçalho (14 bytes): É composto do endereço de 6 bytes de rede da máquina destinatária mais o endereço de 6 bytes da máquina emissora mais o valor do comprimento da mensagem que está sendo enviada no quadro. Este último valor tem 2 bytes.
* Dados (46-1500 bytes): Nesta parte está a mensagem em si que está sendo enviada. Ela pode ter no mínimo 46 e no máximo 1500 bytes de tamanho (já levando em conta o preenchimento de bits). Caso a mensagem tenha menos de 46 bytes, bytes adicionais que não serão lidos são colocados no quadro.
* Engate (4 bytes): O engate consiste em um número com informações redundantes que poderá ser usado para detectar se o quadro recebido está intacto ou foi danificado ao longo do percurso.

## O Controle de Fluxo

Em uma rede, é comum que algumas máquinas consigam receber e processar transmissões mais rapidamente que as demais. Afinal, podem estar ligados em redee um computador bastante antigo e lento e um outro moderno e rápido. Ou então, pode existir na rede um nó que demore mais para processar as mensagens que chegam para ele porque ele recebe um número de mensagens muito maior que as outras máquinas.
Por isso, é imporante garantir que as máquinas que demoram mais para processar sinais recebidos não sejam sobrecarregadas pelas máquinas que são capazes de enviar novos sinais muito rapidamente. É para isso que serve o Controle de Fluxo, que é uma responsabilidade da subcamada LLC da Camada de Enlace de Dados.
Existem dois principais protocolos que podem fazer o controle de fluxo em uma rede. Vamos ver agora quais são eles.

### O Protocolo de Controle de Fluxo Para-e-Espera

Este é um protocolo bastante simples. Ele funciona assim: após o envio de um sinal pela rede, a máquina emissora espera receber como resposta um quadro que avisa que o sinal foi recebido e processado (esta confirmação é chamada de ACK). Só depois de receber este sinal, a máquina emissora envia a próxima parte da mensagem. A máquina receptora só deve enviar um ACK se ela receber a mensagem corretamente. Caso ela não receba a mensagem ou se a receber danificada, ela não devee enviar nada. Se a máquina emissora não receber um ACK depois de algum tempo, ela deve retransmitir a mensagem anterior.
Na prática, este protocolo nunca é usado em redes modernas, pois ele tem uma série de problemas. O mais grave problema é que por causa da necessidade de sempre ter que esperar um ACK, a máquina transmissora não pode aproveitar toda a largura de banda do canal. Além disso, caso a mensagem de ACK seja danificada ou se perca, a máquina transmissora irá enviar desnecessariamente o mesmo sinal. Isso torna este protocolo bastante ineficiente se comparado com protocolos mais modernos.

### O Protocolo de Controle de Fluxo por Janelas Deslizantes

Neste tipo de transmissão, a máquina transmissora sabe quanto de espaço existe no buffer da máquina receptora. Com isso, o nó transmissor pode ficar enviando sinais continuamente sem precisar esperar por confirmação - desde que os sinais não ocupem ao todo mais espaço do que o disponível em buffer da máquina receptora.
Após enviar os dados, a máquina emissora espera receber uma confirmação da receptora. Esta confirmação toma a forma do número que corresponde ao último sinal recebido pela receptora. Com base nisso, o nó emissor já sabe se a máquina destinatária recebeu todos os sinais enviados ou se algum sinal se perdeu no caminho. Em seguida, ela novamente começa a enviar sinais ininterruptamente até preencher todo o espaço em buffer da máquina receptora à partir do sinal cujo número vem depois do último sinal confirmado pela máquina receptora.
Se quiser ver uma animação em flash interativa que mostra um exemplo deste protocolo, você pode clicar aqui.

## O Controle de Erros

Em uma rede é normal que eventualmente um sinal enviado não chegue corretamente ao destino. Muitas coisas podem causar este fenômeno. Por exemplo, falhas de sincronização, hardware defeituoso, colisões, interferência nos cabos, defeitos ou sobrecarga nos buffers.
Por isso é importante que um nó que recebe uma mensagem possa identificar a presença de um erro na transmissão. Existem duas alternativas possíveis em caso de erro: pedir para que o nó emissor envie novamente a mensagem ou tentar consertar o erro detectado. A primeira alternativa é a mais simples e rápida de se implementar e normalmente é o que é feito na maioria das redes. A segunda alternativa requer que uma grande quantidade de informação redundante seja enviada e portanto é algo que prejudica a velocidade da rede. Entretanto, em canais simplex, por exemplo, não temos como requisitar retransmissões. portanto, neste tipo de canal é melhor implementarmos um controle de erros capaz de corrigir eventuais erros de transmissão.

### Controle de Erro por Paridade

O uso de um bit de paridade é uma estratégia que pode ser usada para detectar se uma mensagem está correta ou não. Um bit de paridade é um bit extra que é colocado na mensagem. Se a paridade for par, o bit excedente terá o valor de "0" se o número de "1"s na mensagem for par e "1" se o número de "1"s na mensagem for ímpar. Se a paridade for ímpar, ocorre o contrário: um 0 significa que existe um número ímpar de "1"s na mensagem e um "0" significa que existe um número par e "1"s na mensagem. Veja um exemplo:
O Controle de Erro por Paridade também pode ser usado para fazer com que um nó receptor seja capaz de corrigir os erros por conta própria. Entretanto, para isso é preciso usar mais de um único bit de paridade. Como isso é feito é mostrado no exemplo abaixo:
* Primeiro pega-se a mensagem a ser transmitida. No nosso exemplo, iremos usar o byte 10001100:
* Em seguida, numeramos os índices de cada bit de 1 até 8:
* Cada bit que ocupa uma posição que é uma potência de 2, deve ser usado por um bit de controle cujo valor será definido pela paridade de outros bits. Os outros bits devem ceder espaço para estes bits de controle sendo deslocados mais à direita:
* Perceba que cada índice que não é uma potência de 2 pode ser escrito na forma de uma soma de potências de 2:
* Agora preenchemos os bits de controle da seguinte forma: o bit 1 é o bit que armazena a paridade de todos os bits cujo índice é representado por um número 1 somado à algo. O bit 2 é o bit que armazena a paridade de todos os bits cujo índice é representado por um número 2 somado à algo. E assim por diante:
* A mensagem acima tem a paridade correta. Já a mensagem abaixo:
possui uma paridade contada errada no endereço 4 e 2. Isso indica para nós que o bit da mensafem que está errado é o formado pela soma de 4 e 2. No caso, o sexto bit. Basta invertermos o seu valor e obteremos a mensagem correta.
Pronto! Desta forma, além de detectar se a mensagem está correta ou não, também é possível detectar onde está o erro. Entretanto, o erro só pode ser corretamente detectado e corrigido se existir erro em apenas um único bit. Se houver mais de um erro, esta técnica não funcionará corretamente. Entretanto, se chegarmos ao ponto de termos uma transmissão tão ruim à ponto de esperarmos receber mais de um erro em um único pacote, isso é sinal de que a estrutura da rede deve ser repensada.

### Controle de Erro por Checagem de Redundância Cíclica (CRC)

O CRC é um método bastante simples. Primeiro ele representa os bits enviados na forma de um polinômio. Por exemplo, o conjunto de 16 bits 1001010101010101 é representado pelo polinômio:
$1x^{15}+0x^{14}+0x^{13}+1x^{12}+0x^{11}+1x^{10}+0x^{9}+1x^{8}+0x^{7}+1x^{6}+0x^{5}+1x^{4}+0x^{3}+1x^{2}+0x^{1}+1x^{0}$
Em seguida, este polinômio é dividido por um polinômio gerador fixo. Qual é este polinômio depende do tipo de CRC usado. Por exemplo, o CRC-16 usa $x^{16}+x^{15}+x^{2}+1$ como polinômio gerador. O CRC-CCITT usa $x^{16}+x^{12}+x^{5}+1$ e o CRC-32 usado na maioria dos protocolos de redes locais usa $x^{32}+x^{26}+x^{23}+1^{22}+x^{16}+x^{12}+x^{11}+1^{10}+x^{8}+x^{7}+1^{5}+x^{4}+1^{2}+x$.
Depois de efetuada a divisão, o resto dessa divisão é enviada junto com a mensagem. A eficiência do CRC depende de qual foi o polinôio gerador usado. No caso do CRC-16 e CRC-CCITT, eles são capazes de detectar todas as falhas que ocorrem em apenas um ou dois bits, todos os erros que ocorrerem em um número ímpar de bits, todos os erros que ocorrerem em 16 bits ou menos, 99,997% das falhas em 17 bits e 99,998% das falhas que ocorrerem em 18 ou mais bits. Com isso, as chances de ocorrerem um erro não-detectado são de 1 em 4,3 bilhões. Devido à sua eficiência, o CRC é a técnica de controle de erros mais usada em redes de computadores.