Trabalho I: Mensageiro Local

Neste trabalho, o objetivo é a criação de um mensageiro: Um aplicativo que possibilita o envio de mensagens, similar ao WhatsApp, Telegram, Signal, Skype, ICQ e MSN Messenger. Este mensageiro será composto de um servidor e de um cliente que rodam em computadores diferentes e se comunicam através de um cabo Ethernet. O mensageiro deverá ser capaz de enviar mensagens de texto e também de trocar arquivos de mídia. O servidor precisa funcionar com apenas um cliente, e um cliente se conecta a apenas um servidor, sendo fora do escopo do trabalho a implementação de um mensageiro que suporta mais de duas pessoas.

Implementação do trabalho

Mensagens de texto

Os dois usuários devem ser capazes de fazer envios de mensagem de texto com todos os caracteres disponíveis na codificação UTF-8. Isso inclui por exemplo letras acentuadas e emojis.

As mensagens devem ser enviadas utilizando para-e-espera, onde próxima mensagem só é enviada após a confirmação (ACK) da mensagem anterior.

Arquivos de mídia

Os dois usuários devem ser capazes de fazer envios de qualquer tipo de arquivo de mídia, independente do formato e do tamanho do arquivo.

Visto que arquivos de mídia podem ter tamanhos arbitrários, o uso de janelas deslizantes é necessário independente da quantidade de arquivos enviados de uma só vez.

A janela deve ser volta-N, sendo um bônus implementa janela seletiva. O tamanho da janela é de 16.

Definições de implementação

 [<data e hora>]<Usuário> : mensagem
[<data e hora>]<Usuário> : "Arquivo de midia enviado! O arquivo pode ser encontrado em <caminho_para_arquivo>"

Formato da mensagem de comunicação

O protocolo é inspirado no Kermit e possui os seguintes campos, na ordem que eles são enviados na rede:

Marcador de início Tipo Sequência Tamanho Dados CRC-8
8 bits 6 bits 4 bits 6 bits n bytes 8 bits

A memória é endereçada por byte, então alguns campos serão contemplados por partes de alguns bytes, podendo também utilizar vários bytes. Sugere-se a implementação utilizando bit fields do C ou C++. Um buffer de bytes pode ser reinterpretado (feito cast) como uma struct de bit fields, mas tenha cuidado com o padding que o compilador pode colocar na suas estruturas, além do fato de isso não ser portável em arquiteturas com endianness diferentes (neste trabalho você pode considerar que usaremos apenas processadores little-endian). Os tipos de cada um dos campos serão definidos em aula e seguem.

Ao se codificar inteiros em vários bytes, utilize a codificação little-endian, isto é, o byte menos significativo vem primeiro. Note que isto é diferente do padrão da rede. O padrão da rede é utilizar a codificação big-endian (e a função htons é utilizada para normalizar para big-endian), onde os bytes mais significativos vem primeiro (por exemplo, um IP 127.0.0.1 seria codificado como 0x7f 0x00 0x00 0x01). Se optou por esta escolha simplesmente por uma questão pragmática: Os processadores com que trabalhamos são em sua maioria little-endian.

Requisitos não funcionais

Diagramas de Sequência


Criar diagramas de sequencia

Sugestões de implementação