- Filipe Borba e Frederico Curti
- Professor : Rafael Corsi
- Auxiliar de ensino : Eng. Eduardo Marossi
O projeto 1 da disciplina de Camada Física da Computação teve por objetivo conectar dois computadores através de um Arduino e transmitir um arquivo de tamanho definido entre os dois. Para tanto, utilizou-se o método de comunicação LoopBack.
O funcionamento do programa é simples. O arquivo aplicacao.py
deve ser iniciado através do comando de terminal python aplicacao.py
; e um papel (Client ou Server) deve ser selecionado.
- Client: seleciona um arquivo e transmite-o para o Server.
- Server: fica sempre pronto para receber um arquivo.
O diagrama a seguir, exemplifica essa relação:
Essa dinâmica pode ser resumida em 4 camadas principais de funções: Aplicação (Client e Server), Enlace (Enlace, EnlaceRx, EnlaceTx), Física e Meio.
- A camada Aplicação é aquela que contém o Client e o Server, os quais controlam a programação e são a saída e a entrada do arquivo, respectivamente.
- A camada Enlace é responsável por tornar o canal de comunicação entre o Client e o Server confiável, sendo que o EnlaceRx é para o recebimento e o EnlaceTx é para a transmissão dos arquivos.
- A camada Física é responsável por serializar e desserializar os dados, enquanto que o Meio pode ser visualizado como um fio que conecta a camada Física do Client com a do Server.
Esse projeto consiste na criação de um protocolo de comunicação entre o server e client do Projeto 1. Isso é realizado através do encapsulamento dos dados a serem enviados e recebidos num pacote que permite uma comunicação mais eficiente entre as partes. A utilização de um protocolo é benéfica, pois:
- Minimiza erros de envio através de vários pacotes que são checados.
- Permite o envio de arquivos de tamanho desconhecido entre os papéis.
O controle desse pacote é feito através de um cabeçalho (HEAD) e um "fim de pacote" (EOF). Esse controle deve ser igual para os dois papéis, a fim de que haja a comunicação. Esse cabeçalho pode possuir informações importantes, como o tamanho total do arquivo, o tipo de arquivo, um contador para incrementar a cada pacote enviado, entre outras informações relativamente relevantes.
No HEAD, temos:
- Constante Fixa (Int8ub)
- Tamanho do Arquivo (Int16ub)
- Tipo do Arquivo (Array)
Definida a quantiade de bytes reservada para o controle de pacote, podemos calcular o protocol overhead, expressa por: Overhead = Tamanho Total/Tamanho Payload O Overhead desse protocolo é, então, 100,028%.
Throughput é a definião de quão rápido um dado pode ser enviado numa rede, levando em consideração a taxa de envio (baudrate), o overhead de encapsulamento e de serialização. O Baudrate é a taxa em bits por segundo (bps) com a qual uma rede consegue trasmitir bits. A dos arduínos em questão é de 115200 bps.
Esse projeto consiste na criação de uma comunicação de confirmação entre o servidor e cliente ("handshake"). O Handshake implementado consiste no envio de um pacote "SYN" do cliente, que é respondido pelo servidor por um "SYN+ACK" em caso de sucesso de comunicação ou um "SYN+NACK" em caso de falha. Por fim, se o cliente recebe o SYN+ACK, responde com um ACK e a transferência começa, caso contrário ele tenta enviar um SYN novamente.
O HEAD dos pacotes de comando possui 5 campos: start, size, filename, ext e type (assim como o HEAD do projeto 2!). Os pacotes SYN, ACK, SYN+ACK e SYN+NACK são construídos da mesma forma, porém, seu "type" é diferente. Através do método buildCommandPacket(commandType) é possível construir esses pacotes com types diferentes. No caso, os campos são preenchidos da seguinte maneira no método:
- start = 0xFF
- size = 0x00
- filename = "NULL"
- ext = "NULL"
- type = commandType sendo commandType uma String contendo "SYN", "ACK, "SYN+ACK" ou "SYN+NACK" (para o caso de um pacote de dados, o tipo é "PAYLOAD").
Os pacotes, então, são representados da seguinte maneira:
Depois, as imagens a seguir representam o envio e recepção dos pacotes como uma máquina de estados. Desta forma, é possível visualizar bem o funcionamento do programa:
Por fim, é possível notar que deve existir um "timeout" para que o programa não fique interrompido na mesma tarefa. O tempo para timeout escolhido foi de 5 segundos, pois consideramos o suficiente para o envio e processamento do handshake.
Esse projeto consiste na melhora da confiança do protocolo ao receber e enviar dados. Isso ocorre, porque através de pequenos pacotes que fragmentam o arquivo total, existem menos falhas e, caso elas ocorram, é mais fácil tratá-las. Imagine enviar se uma falha ocorrer, mas ao invés de reenviar o tamanho do arquivo, apenas uma fração bem pequena é reenviada!
Para tanto, utilizamos um tamanho máximo dos "pacotinhos" de 2048 bytes e dividimos o tamanho do arquivo total por esses bytes. Caso o resto da divisão dê exata, não é necessário adicionar mais um pacote para enviar aquele restante de bytes.
O HEAD, então, teve de ser modificado. Agora ele possui os campos:
- size = Tamanho total do arquivo a ser enviado,
- slicesize = 2048 bytes (tamanho dos pacotinhos),
- filename = Nome do Arquivo (até 16 caracteres)
- ext = Extensão (PNG, JPEG, JPG...)
- type = Tipo de Arquivo (SYN, ACK, NACK, PAYLOAD)
- index = Array com o [Indice do Pacote, Indice Total]
Dessa vez, utilizamos um timeout de 4 segundos, pois é suficiente para Handshake e início de envio do primeiro pacotinho.
Para realizar o checksum, utilizamos um gerador de hash chamado MD5, que gera uma chave única para um determinado payload de pacote. Com isso, conseguimos realizar um checksum, mandar o hash através do pacote e realizar o checksum novamente, tendo certeza de que o pacote certo chegou.