20
Rede de Computadores
UFMG
16
Rede de Computadores
UFMG
1
Rede de Computadores
UFMG
25
Rede de Computadores
UFMG
20
Rede de Computadores
UFMG
25
Rede de Computadores
UFMG
20
Rede de Computadores
UFMG
16
Rede de Computadores
UFMG
16
Rede de Computadores
UFMG
26
Rede de Computadores
UFMG
Texto de pré-visualização
Trabalho Prático 2 Redes de Sensores Sem Fio Entrega Individual Data de Entrega 08 de janeiro de 2025 as 2359 Introdução As Redes de Sensores Sem Fio RSSF representam uma tecnologia crucial para a coleta de dados em tempo real em ambientes diversos com aplicações como monitoramento ambiental automação industrial e até atuações dentro de seres vivos Essas redes consistem em pequenos dispositivos sensores geralmente distribuídos em uma área capazes de captar informações como temperatura umidade pressão etc Cada sensor se comunica sem fio com outros dispositivos ou diretamente com um servidor central permitindo a criação de sistemas distribuídos e escaláveis Nas figuras abaixo um exemplo de um diagrama de rede e um sensor ambos para situações embaixo dágua Imagem 1 Sala de Espera do jogo Among Us Para ilustrar o funcionamento de uma RSSF este trabalho prático tem como objetivo simular uma rede composta por três tipos de sensores espalhados em uma região delimitada Os sensores serão responsáveis por coletar e reportar informações de forma periódica Esses sensores se comunicarão com um servidor central utilizando um modelo publishsubscribe onde as mensagens serão enviadas a tópicos específicos de acordo com o tipo de sensor Clientes conectados a esses tópicos poderão receber os dados e atualizar suas medições com base na proximidade aos sensores Objetivo Você desenvolverá 2 programas para o sistema de salas de espera utilizando apenas as funcionalidades da biblioteca de sockets POSIX e a comunicação via protocolo TCP O código do servidor deverá utilizar múltiplas threads para a manutenção das múltiplas conexões As próximas seções detalham o que cada entidade servidor e cliente deve fazer Os objetivos deste trabalho são Desenvolver um servidor utilizando a interface de sockets na linguagem C Desenvolver um cliente utilizando a interface de sockets na linguagem C Permitir que múltiplos clientes sejam conectados ao servidor e que ele encaminhe as mensagens dos sensores Fazer com que os clientes reportem as medições de tempos em tempos e que atualizem suas medidas com base nos vizinhos Protocolo O protocolo de comunicação entre o cliente e o servidor será modelado de tal forma que as operações sejam representadas pela seguinte estrutura struct sensormessage char12 type int coords2 float measurement Abaixo descrição de cada uma das propriedades type Essa propriedade armazena o tipo do sensor Neste trabalho serão 3 diferentes temperature que vai medir a temperatura do ambiente humidity para sensores de umidade airquality para medir a qualidade do ar coords Essa propriedade representa as coordenadas do sensor no espaço Neste trabalho será considerado um grid 10x10 onde o primeiro valor do vetor representa em que linha o sensor está e o segundo a coluna measurement Já essa propriedade representa a medição de cada sensor que ele mantém e envia em cada intervalo de tempo além de atualizar conforme os vizinhos Inicialização O código do cliente deve ser executado passando como argumento as coordenadas Conforme mencionado anteriormente o espaço dos sensores é um grid 10x10 de forma que as coordenadas em cada eixo vão variar de 0 à 9 e devem ser passadas da seguinte forma client 127001 51511 type temperaturehumidityairquality coords x y O usuário pode passar parâmetros errados na hora de inicializar o cliente onde a ordem prioritária dos erros bem como as mensagens que devem ser exibidas são Tabela 1 Erros de inicialização e tratativas Descrição do Erro Exemplo Mensagem Faltando argumentos client 127001 51511 type temperature coords 5 Error Invalid number of arguments Argumento type faltando client 127001 51511 tipo temperature coords 5 7 Error Expected type argument Tipo de sensor não definido client 127001 51511 type pression coords 5 7 Error Invalid sensor type Argumento coords faltando client 127001 51511 type temperature pos 5 7 Error Expected coords argument Coordenadas fora do intervalo client 127001 51511 type temperature coords 10 7 Error Coordinates must be in the range 09 OBS Após cada mensagem de erro devese exibir também a seguinte mensagem padrão na linha de baixo Usage client serverip port type temperaturehumidityairquality coords x y Também erros que não estão listados como passar chars ao invés de inteiros não precisam ser tratados e não serão testados na avaliação Exemplo completo de erro e mensagem client 127001 51511 type temperature coords 5 Error Invalid number of arguments Usage client serverip port type tipos coords x y onde tipos temperaturehumidityairquality só para destacar que é na mesma linha Uma vez corretamente inicializado o sensor vai realizar sua medição que consiste em um valor aleatório no intervalo descrito na Tabela 2 A cada intervalo de tempo também descrito nesta tabela o cliente vai mandar uma mensagem para o servidor informando sua localização tipo e medição Tabela 2 Valores e Intervalos dos Sensores Tipo do sensor Intervalo das medições Intervalo entre mensagens Temperatura ºC 200 400 5 segundos Humidade 100 900 7 segundos Qualidade do ar μgm³ 150 300 10 segundos Funcionamento da Rede Após a inicialização dos valores o funcionamento do sistema segue uma abordagem baseada no padrão publishsubscribe Nesse sistema cada sensor já é inscrito no tópico correspondente ao seu tipo por exemplo temperature humidity ou airquality de forma que todas as mensagens enviadas pelos sensores de um determinado tipo são transmitidas para todos os sensores do mesmo tipo O servidor é responsável por gerenciar os tópicos garantindo que as mensagens sejam encaminhadas corretamente para os sensores interessados Os sensores enviam suas medições periodicamente para o tópico correspondente e o servidor as propaga para todos os sensores inscritos Cada sensor ao receber uma nova medição de outro sensor utiliza essa informação para corrigir sua própria medição com base na proximidade e na diferença entre os valores caso seja um dos três sensores mais próximos Isso significa que somente a primeira medição quanto o cliente é inicializado que escolhida aleatoriamente o restante são só ajustes nessa escolha A fórmula para atualizar a medição é dada da seguinte forma 𝑛𝑜𝑣𝑎𝑚𝑒𝑑𝑖çã𝑜 𝑚𝑒𝑑𝑖çã𝑜𝑎𝑡𝑢𝑎𝑙 0 1 1 𝑑 1 𝑚𝑒𝑑𝑖çã𝑜𝑟𝑒𝑚𝑜𝑡𝑎 𝑚𝑒𝑑𝑖çã𝑜𝑎𝑡𝑢𝑎𝑙 Onde novamedição é o novo valor do sensor após a correção mediçãoatual é o valor atual do sensor mediçãoremota é o valor enviado pelo sensor remoto d é a distância euclidiana entre o sensor atual e o sensor remoto 𝑑 𝑥1 𝑥2 2 𝑦1 𝑦2 2 Essa fórmula leva em conta tanto a diferença entre o valor do sensor que recebeu a mensagem e o valor atual quanto a proximidade entre os sensores Se após a atualização o valor corrigido ultrapassar o intervalo permitido Tabela 2 ele deve ser ajustado automaticamente para o limite mais próximo inferior ou superior Isso assegura que todas as medições permaneçam válidas dentro do contexto da aplicação Conforme já citado um aspecto crucial do sistema é o gerenciamento dos vizinhos mais próximos Cada sensor deve manter a informação de seus vizinhos pois vai atualizar sua medição somente com base nos três sensores mais próximos de sua posição descartando as medidas dos outros Manter todos os vizinhos e não só os 3 mais próximos é importante porque caso um dos sensores próximos saia do sistema o sensor atual deve identificar o próximo da fila para substituílo na lista de vizinhos mais próximos Essa feature é importante considerando as RSSF que têm que lidar constantemente com sensores saindo da rede eg sem bateria destruído pelo ambiente etc Descoberta Dinâmica de Sensores A descoberta de novos sensores no sistema é dinâmica Quando um novo sensor entra na rede ele pode começar recebendo e consequentemente utilizando para atualizar a sua medições de sensores que não necessariamente são seus vizinhos mais próximos considerando todos da rede devido à falta de conhecimento inicial sobre o ambiente Conforme novas mensagens são recebidas o sensor atual ajusta sua lista de vizinhos e passa a priorizar as medições dos mais próximos Para exemplificar considere o seguinte cenário um ambiente com 5 sensores do mesmo tipo e um novo sensor desse mesmo tipo entra no sistema Se ele receber mensagens na ordem do mais distante para o mais próximo ele realizará 5 atualizações até estabilizar com os três vizinhos mais próximos Se a ordem for do mais próximo para o mais distante apenas 3 atualizações serão realizadas pois ele estabiliza sua lista de vizinhos antes de processar as medições mais distantes Esse comportamento dinâmico ilustra o procedimento real de muitos sistemas em RSSF para descobrir seus vizinhos e a fórmula de atualização também considera esse caso ao considerar a distância e consequentemente diminuir a influência de sensores distantes Exibição das mensagens O servidor deve exibir todas as mensagens recebidas em um formato padronizado permitindo fácil rastreamento e depuração log type sensor in xy measurement measurement onde type Tipo do sensor temperature humidity ou airquality xy Coordenadas do sensor que enviou a mensagem measurement Valor da medição enviado Os clientes por sua vez vão exibir todas as mensagens que chegam para ele ou seja todas do mesmo tipo dele Isso inclui a deles mesmos já que não devem exibir nada ao enviar uma mensagem O formato de exibição é o mesmo do servidor mas com um campo a mais log type sensor in xy measurement measurement action status Esse último campo descreve o tratamento realizado daquela mensagem devendo ser exibido not neighbor Caso o sensor que recebeu considere que o emissor está muito longe para ser considerado vizinho e descarta a medição Essa ação só é possível caso o receptor já tenha três vizinhos e essa nova mensagem venha de um mais distante que esses três correction of value Caso onde o sensor é um vizinho e portanto é feita correção na medição O valor a ser exibido é o que vai ser corrigido da medição atual arredondado para quatro casas decimais Se negativo indicar com sinal na frente same location Caso o sensor emissor esteja na mesma célula que o receptor e portanto não deve ser considerada não é vizinho removed Caso em que o sensor saiu do sistema explicado no tópico abaixo Perceba que é possível sensores ocuparem o mesmo espaço do grid não bloqueamos isso na inicialização e como não passamos nenhum ID de cada sensor não temos como saber se a mensagem que chegou é a que o próprio sensor enviou ou de outro Assim para simplificar vamos considerar como não vizinho e descartar todas as medições da mesma célula que o sensor Obs Existe um no final do log que significa para adicionar mais uma quebra de linha para separar melhor os logs no terminal dando uma linha em branco entre eles Encerramento de um sensor Os clientes não vão receber nenhum input por parte do usuário Isso é proposital já que em Redes de Sensores Sem Fio os dispositivos são autônomos e descartáveis Assim para finalizar o sensor é necessário parar o processo do cliente Ctril C o que representa a destruiçãoinatividade do dispositivo O servidor por sua vez vai perceber que o cliente foi desconectado e deve exibir o log padrão mas com medida negativa 10000 e enviar essa medição para os sensores do mesmo tipo como se fosse uma medição normal desse sensor só que com valor negativo log type sensor in xy measurement 10000 Os clientes por sua vez devem interpretar que essa medição negativa representa que esse sensor não está mais disponível e devem removêlo de suas bases de dados Devem exibir a action como removed Exemplo de Execução Esta seção apresenta alguns exemplos de execuções do sistema A fim de facilitar a explicação as tabelas a seguir detalham o passo a passo das mensagens ao longo do tempo Nesse primeiro exemplo temos dois sensores do mesmo tipo se conectando no servidor inicialmente sem sensores Considere que o Sensor 1 teve medição inicial de 25 ºC e o segundo 20 ºC e que o envio e recebimento de mensagens é instantâneo Tempo 1 s Servidor Terminal 1 Terminal 2 T0 client 127001 51511 type temperature coords 2 2 T1 T2 client 127001 51511 type temperature coords 4 4 T3 T4 T5 log temperature sensor in 22 measurement 250000 log temperature sensor in 22 measurement 250000 action same location log temperature sensor in 22 measurement 250000 action correction of 01306 T6 T7 log temperature sensor in 44 measurement 201306 log temperature sensor in 44 measurement 201306 action correction of 01272 log temperature sensor in 44 measurement 201306 action same location T8 T9 T10 log temperature sensor in 22 measurement 248728 log temperature sensor in 22 measurement 248728 log temperature sensor in 22 measurement 248728 action same location action correction of 01239 T11 T12 log temperature sensor in 44 measurement 202542 log temperature sensor in 44 measurement 202545 action correction of 01206 log temperature sensor in 44 measurement 202545 action same location Abaixo um exemplo com 3 sensores um de cada tipo e entra um quarto sensor Considere as medidas iniciais como Sensor 1 Tipo temperature posição 22 medição inicial 250 Sensor 2 Tipo humidity posição 33 medição inicial 500 Sensor 3 Tipo airquality posição 11 medição inicial 220 Sensor 4 Tipo temperature posição 44 medição inicial 200 Tempo Servidor Terminal 1 Terminal 2 Terminal 3 Terminal 4 T0 client 127001 51511 type temperature coords 2 2 client 127001 51511 type humidity coords 3 3 client 127001 51511 type airquality coords 1 1 T1 T2 T3 client 127001 51511 type temperature coords 4 4 T4 T5 log temperature sensor in 22 log temperature sensor in 22 log temperature sensor in 22 measurement 250000 measurement 250000 action same location measurement 250000 action correction of 01306 T6 T7 log humidity sensor in 33 measurement 500000 log humidity sensor in 33 measurement 500000 action same location T8 log temperature sensor in 44 measurement 201306 log temperature sensor in 44 measurement 201306 action correction of 01272 log temperature sensor in 44 measurement 201306 action same location T9 T10 log temperature sensor in 22 measurement 248728 log airquality sensor in 11 measurement 220000 log temperature sensor in 22 measurement 248728 action same location log airquality sensor in 11 measurement 220000 action same location log temperature sensor in 22 measurement 248728 action correction of 01239 T11 T12 T13 log temperature sensor in 44 measurement 202545 log temperature sensor in 44 measurement 202545 action correction of 01206 log temperature sensor in 44 measurement 202545 action same location T14 log humidity sensor in 33 measurement 500000 log humidity sensor in 33 measurement 500000 action same location Por fim um exemplo em que um sensor se desconecta Considere os seguintes sensores Sensor 1 Tipo humidity posição 22 medição atual de 500 Sensor 2 Tipo humidity posição 23 medição atual de 550 Sensor 3 Tipo humidity posição 32 medição atual de 580 Sensor 4 Tipo humidity posição 33 medição atual de 520 Sensor 5 Tipo humidity posição 99 medição atual de 600 Cada um entrou no sistema com um segundo de diferença em ordem crescente ou seja primeiro o sensor 1 vai mandar mensagem depois o 2 etc Nesse exemplo os sensores já trocaram algumas mensagens de forma que os dispositivos 1 2 e 3 e 4 são vizinhos entre si Contudo quando o sensor 2 sai do sistema os outros consideram o 5 como um vizinho próximo Tempo Terminal 1 Terminal 2 Terminal 3 Terminal 4 Terminal 5 T0 log humidity sensor in 22 measurement 500000 action same location log humidity sensor in 22 measurement 500000 action correction of 02500 log humidity sensor in 22 measurement 500000 action correction of 01000 log humidity sensor in 22 measurement 500000 correction of 00828 log humidity sensor in 22 measurement 500000 action not neighbor T1 log humidity sensor in 23 measurement 547500 action correction of 02375 log humidity sensor in 23 measurement 547500 action action same location log humidity sensor in 23 measurement 547500 action correction of 02755 log humidity sensor in 23 measurement 547500 action correction of 01416 log humidity sensor in 23 measurement 547500 action correction of 00514 T2 log humidity sensor in 32 measurement 483755 action correction of 00931 log humidity sensor in 32 measurement 483755 action correction of 02640 log humidity sensor in 32 measurement 483755 action same location log humidity sensor in 32 measurement 483755 action correction of 01842 log humidity sensor in 32 measurement 483755 action correction of 01132 T3 log humidity sensor in 33 measurement 518746 action correction of 00717 log humidity sensor in 33 measurement 518746 action correction of 01306 log humidity sensor in 33 measurement 518746 action correction of 01750 log humidity sensor in 33 measurement 518746 action same location log humidity sensor in 33 measurement 518746 action correction of 00839 T4 log humidity sensor in 99 measurement 597515 action not neighbor log humidity sensor in 99 measurement 597515 action not neighbor log humidity sensor in 99 measurement 597515 action not neighbor log humidity sensor in 99 measurement 597515 action not neighbor log humidity sensor in 99 measurement 597515 action same location T5 T6 log humidity sensor in 23 measurement 10000 action removed Ctril C Cliente se desconecta Servidor manda mensagem com medida 10000 log humidity sensor in 23 measurement 10000 action removed log humidity sensor in 23 measurement 10000 action removed log humidity sensor in 23 measurement 10000 action removed T7 log humidity sensor in 22 measurement 502161 action same location log humidity sensor in 22 measurement 502161 action correction of 00833 log humidity sensor in 22 measurement 502161 action correction of 00687 log humidity sensor in 22 measurement 502161 action correction of 00875 T8 T9 log humidity sensor in 32 measurement 486337 action correction of 00791 log humidity sensor in 32 measurement 486337 action same location log humidity sensor in 32 measurement 486337 action correction of 01586 log humidity sensor in 32 measurement 486337 action correction of 01079 T10 log humidity sensor in 33 measurement 516473 action correction of 00626 log humidity sensor in 33 measurement 516473 action correction of 01507 log humidity sensor in 33 measurement 516473 action same location log humidity sensor in 33 measurement 516473 action correction of 00834 T11 log humidity sensor in 99 measurement 594727 action correction of 00851 log humidity sensor in 99 measurement 594727 action correction of 01046 log humidity sensor in 99 measurement 594727 action correction of 00825 log humidity sensor in 99 measurement 594727 action same location Detalhes de implementação Gerenciamento de Sensores O servidor será responsável por manter o registro de todos os sensores conectados incluindo suas coordenadas e tipo Os sensores devem manter a lista dos vizinhos mais próximos Caso um vizinho caia o sensor deve atualizar sua lista promovendo o próximo da fila à posição de vizinho próxmo Tipos de Sensores Apenas três tipos de sensores serão aceitos temperature humidity e airquality Qualquer tipo diferente deve resultar em um erro e impedir a execução do cliente Coordenadas dos Sensores As coordenadas dos sensores devem ser especificadas ao iniciar o cliente e precisam estar dentro do intervalo 0 9 Caso as coordenadas estejam fora do intervalo ou não sejam numéricas o cliente deve exibir uma mensagem de erro e não iniciar Mensagens e Tópicos Cada tipo de sensor possui um tópico exclusivo no qual serão publicadas e recebidas as mensagens Mensagens de sensores do mesmo tipo devem ser encaminhadas apenas para outros sensores do mesmo tipo Atualização de Medições As medições iniciais são aleatórias dentro dos intervalos definidos mas todas as atualizações subsequentes devem usar a fórmula de correção com base nos vizinhos mais próximos Apenas os três vizinhos mais próximos serão usados para corrigir medições Se não houver vizinhos a medição fica sempre a mesma Novos Sensores Sensores que entram dinamicamente no sistema podem usar medições de outros sensores fora de sua vizinhança real até descobrirem os vizinhos mais próximos Limites e Formatação As medições devem ser exibidas com até 4 casas decimais As coordenadas dos sensores no log devem estar no formato xy Desempenho e Limites Serão testados até 12 sensores simultâneos Certifiquese de que o sistema funcione corretamente dentro deste limite Erros e Validações Mensagens de erro específicas devem ser exibidas para parâmetros inválidos tipo ou coordenadas impedindo o cliente de iniciar Sensores sobrepostos Mais de um sensor podem ocupar o mesmo espaço no sistema de tipos iguais ou diferentes As medições da mesma localização do sensor não são usadas para atualizar as medições e nem são consideradas vizinhos Ou seja se só houver sensores num mesmo local ninguém atualiza as medições Desenvolvimento O projeto requer a implementação de dois componentes essenciais um servidor e um cliente ambos baseados no protocolo TCP É crucial garantir que ambos os componentes sejam compatíveis tanto com o IPv4 quanto com o IPv6 proporcionando flexibilidade na escolha do endereço IP Para configurar o servidor corretamente este deve ser capaz de receber seguindo rigorosamente essa ordem o tipo de endereço desejado v4 para IPv4 ou v6 para IPv6 e um número de porta especificado na linha de comando Recomendase a utilização da porta 51511 para manter a padronização do projeto Da mesma forma os clientes precisam receber também rigorosamente nessa ordem o endereço IP do servidor e o número de porta para estabelecer a conexão com sucesso Certifiquese de que ambos os componentes sejam configurados de acordo com essas diretrizes para uma integração eficaz e a comunicação adequada entre servidor e cliente A seguir um exemplo de execução dos programas em dois terminais distintos IPv4 no terminal 1 server v4 51511 no terminal 2 client 127001 51511 type temperature coords 1 1 no terminal 3 client 127001 51511 type airquality coords 2 2 IPv6 no terminal 1 server v6 51511 no terminal 2 client 1 51511 type humidity coords 5 6 no terminal 3 client 1 51511 type humidity coords 6 5 Sobre Threads O uso de threads em servidores é uma abordagem eficiente para lidar com múltiplas conexões simultâneas Em um servidor multithread cada cliente conectado é gerenciado por uma thread separada permitindo que o servidor processe várias requisições de forma paralela Essa arquitetura tem várias vantagens com talvez a principal de evitar que a execução de uma operação mais demorada por um cliente bloqueie o atendimento de outros garantindo maior responsividade do sistema No contexto deste trabalho prático o servidor será responsável por criar uma nova thread para cada cliente que se conecta Cada thread atuará de forma independente lidando com as mensagens daquele cliente Ao mesmo tempo o servidor principal continuará rodando em sua thread principal aceitando novas conexões sem interrupções Essa abordagem permite manter um fluxo contínuo de comunicação entre os sensores e o servidor assegurando que todas as mensagens sejam tratadas adequadamente mesmo em cenários com vários sensores conectados simultaneamente Para aqueles que não conhecem ou desejam relembrar esses conceitos recomendo essa playlist em especial os vídeos 5 6 e 7 Materiais para Consulta e Dicas Capítulo 2 e 3 do livro sobre programação com sockets disponibilizado no Moodle Playlist de programação com sockets do professor Ítalo Cunha O guia de programação em rede do Beej httpbeejusguidebgnet tem bons exemplos de como organizar um servidor Implemente o trabalho por partes Por exemplo implemente o tratamento das múltiplas conexões depois crie os formatos das mensagens e por fim trate os tópicos e as especifidades Procure resolver os desafios da maneira mais simples possível Avaliação O trabalho deve ser realizado individualmente e deve ser implementado com a linguagem de programação C não sendo permitida a utilização de C utilizando somente a biblioteca padrão interface POSIX de sockets de redes Deve ser possível executar seu programa no sistema operacional Linux e não deve utilizar bibliotecas Windows como o winsock Seu programa deve interoperar com qualquer outro programa implementando o mesmo protocolo você pode testar com as implementações dos seus colegas Procure escrever seu código de maneira clara com comentários pontuais e bem identados Isto facilita a correção dos monitores e tem impacto positivo na avaliação Correção Semiautomática Seu servidor será corrigido de forma semiautomática por uma bateria de testes Cada teste verifica uma funcionalidade específica do servidor Para a correção os seguintes testes serão realizados com IPv4 e IPv6 Conexão de múltiplos clientes 10 Gerenciamento correto dos vizinhos descoberta dinâmica 15 Encaminhamento correto das mensagens para os clientes 15 Atualização correta das medições 15 Impressão correta das mensagens 10 Fechamento de conexão 10 Tratativa dos erros 5 Documentação 20 Informações importantes Cada aluno deve entregar documentação em PDF de até 4 páginas duas folhas sem capa utilizando fonte Arial tamanho 12 e figuras de tamanho adequado ao tamanho da fonte A documentação deve discutir desafios dificuldades e imprevistos do projeto bem como as soluções adotadas para os problemas Atenção Será dado grande importância a parte da discussão dos desafios encontrados pois as dificuldades ao longo do projeto sempre existem A documentação corresponde a 20 dos pontos do trabalho mas só será considerada para as funcionalidades implementadas corretamente Será utilizado um sistema para detecção de código repetido portanto não é admitido cola de trabalhos Será adotada média harmônica entre as notas da documentação e da execução o que implica que a nota final será 0 se uma das partes não for apresentada Cada aluno deve entregar além da documentação o código fonte em C e um Makefile para compilação do programa Instruções para submissão e compatibilidade com o sistema de correção semiautomática O Makefile deve compilar o cliente em um binário chamado client e o servidor em um binário chamado server dentro de uma pasta chamada bin na raiz do projeto Seu programa deve ser compilado ao se executar apenas o comando make ou seja sem a necessidade de parâmetros adicionais A entrega deve ser feita no formato ZIP com o nome seguindo o seguinte padrão TP2MATRICULAzip Desconto de Nota por Atraso Os trabalhos poderão ser entregues até a meianoite do dia especificado para a entrega Não serão aceitos trabalhos com atraso Relatorio do Projeto de Salas de Espera em Redes de Sensores January 18 2025 1 Introducao Foi descrito nesse documento um desenvolvimento de um sistema de salas de espera para Redes de Sensores Sem Fio RSSF utilizando sockets POSIX sobre TCP O sistema e composto por dois programas em linguagem C um servidor multithread e um cliente que representa um sensor Os clientes podem ser de trˆes tipos temperature humidity e air quality e enviam suas leituras de forma periodica ao servidor O servidor e responsavel por gerenciar todos os sensores conectados iden tificando o tipo de cada um que atua como um topico de publishsubscribe Assim todas as mensagens publicadas pelos sensores de um determinado tipo sao encaminhadas para todos os sensores desse mesmo tipo 2 Objetivos Os objetivos principais deste trabalho sao Desenvolver um servidor que gerencie multiplas conexoes de clientes por meio de threads Garantir que o servidor propague as leituras de sensores do mesmo tipo para todos os clientes que pertencam ao mesmo topico tipo Fazer com que os clientes reportem as medicoes periodicamente e atu alizem suas leituras usando as informacoes de ate trˆes vizinhos mais proximos conforme distˆancia euclidiana Demonstrar o tratamento correto de erros de inicializacao no cliente e de desconexao de sensores 1 3 Descricao do Problema Em Redes de Sensores Sem Fio RSSF cada dispositivo sensor reporta leituras do ambiente temperatura umidade ou qualidade do ar em um grid de tamanho 1010 no qual as coordenadas variam de 0 a 9 Sempre que um sensor recebe a leitura de outro sensor do mesmo tipo ele verifica se o emissor esta entre os trˆes vizinhos mais proximos em termos de distˆancia euclidiana e caso sim aplica uma formula de correcao em sua propria medicao 31 Formula de Correcao A correcao e dada por nova medicao medicao atual01 1 d 1medicao remotamedicao atual onde d e a distˆancia euclidiana entre os dois sensores no grid medicao remota e a leitura recebida medicao atual e a leitura do sensor local antes da correcao 4 Visao Geral da Solucao A solucao se baseia em duas aplicacoes server e client 41 Servidor Cria um socket TCP compatıvel com IPv4 ou IPv6 Fica em listen aceitando conexoes de clientes Para cada cliente conectado cria uma nova thread que fica responsavel por receber as mensagens desse cliente Ao receber uma mensagem sensor message o servidor 1 Imprime em seu console o log do sensor 2 Reenvia a mensagem a todos os clientes do mesmo tipo topico Se o cliente encerrar a conexao repentinamente via CtrlC o servi dor 2 1 Identifica a desconexao 2 Gera uma mensagem com measurement 10000 indicando que o sensor saiu do sistema 3 Faz o broadcast dessa mensagem para os clientes do mesmo tipo 42 Cliente Sensor Conectase ao servidor via TCP fornecendo IP do servidor pode ser IPv4 ou IPv6 Porta de conexao por exemplo 51511 Tipo do sensor temperature humidity air quality Coordenadas x y do grid Gera sua medicao inicial de forma aleatoria dentro dos intervalos es pecificados temperature entre 200 e 400 humidity entre 100 e 900 air quality entre 150 e 300 Periodicamente envia sua propria medicao ao servidor temperature a cada 5 segundos humidity a cada 7 segundos air quality a cada 10 segundos Recebe assıncronamente numa thread dedicada as mensagens de outros sensores do mesmo tipo Se a mensagem vier de um sensor que nao seja vizinho entre os 3 mais proximos exibe action not neighbor Se vier de um sensor na mesma celula x y exibe action same location Caso o sensor seja um dos 3 mais proximos aplica a formula de correcao exibe action correction of Em caso de mensagem com measurement 10000 exibe action removed e remove o sensor do cadastro local 3 5 Estrutura do Codigo Para simplificar todo o codigo esta a seguir em blocos lstlisting 51 Arquivo sensor messageh Listing 1 sensormessageh 1 ifndef SENSORMESSAGEH 2 define SENSORMESSAGEH 3 4 include stdioh 5 include stdlibh 6 include stringh 7 include unistdh 8 include arpaineth 9 include syssocketh 10 include pthreadh 11 include mathh 12 include timeh 13 14 define MAXTYPELEN 12 15 16 struct sensormessage 17 char typeMAXTYPELEN temperature humidity ou airquality 18 int coords 2 coords 0 x coords 1 y 19 float measurement valor da m e d i o 20 21 22 ssizet readallint sockfd void buffer sizet size 23 ssizet writeallint sockfd const void buffer sizet size 24 int sendsensormessage int sockfd const struct sensormessage msg 25 int recvsensormessage int sockfd struct sensormessage msg 26 double distanceeuclid int x1 int y1 int x2 int y2 27 28 endif 4 52 Arquivo sensor messagec Listing 2 sensormessagec 1 include sensormessageh 2 3 ssizet readallint sockfd void buffer sizet size 4 sizet bytesRead 0 5 char buf char buffer 6 while bytesRead size 7 ssizet result readsockfd buf bytesRead size bytesRead 8 if result 0 9 return result Erro ou c o n e x o fechada 10 11 bytesRead result 12 13 return ssizet bytesRead 14 15 16 ssizet writeallint sockfd const void buffer sizet size 17 sizet bytesSent 0 18 const char buf const char buffer 19 while bytesSent size 20 ssizet result writesockfd buf bytesSent size bytesSent 21 if result 0 22 return result Erro 23 24 bytesSent result 25 26 return ssizet bytesSent 27 28 29 int sendsensormessage int sockfd const struct sensormessage msg 30 ssizet n writeallsockfd msg sizeofstruct sensormessage 31 return n sizeofstruct sensormessage 0 1 32 33 5 34 int recvsensormessage int sockfd struct sensormessage msg 35 ssizet n readallsockfd msg sizeofstruct sensormessage 36 if n 0 return 1 37 if n ssizetsizeofstruct sensormessage return 1 38 return 0 39 40 41 double distanceeuclid int x1 int y1 int x2 int y2 42 double dx doublex1 x2 43 double dy doubley1 y2 44 return sqrtdx dx dy dy 45 53 Arquivo serverc Listing 3 serverc 1 2 Servidor TCP IPv4IPv6 que recebe mensagens de sensores e faz broadcast 3 para todos os sensores do mesmo tipo gerenciando m l t i p l a s c o n e x e s com threads 4 5 6 include sensormessageh 7 include netdbh 8 include errnoh 9 10 Estrutura para manter i n f o r m a e s de cada cliente conectado 11 typedef struct clientnode 12 int sockfd 13 pthreadt threadid 14 char typeMAXTYPELEN 15 int coords 2 16 float lastmeasurement 17 struct clientnode next 18 clientnodet 19 20 clientnodet gclients NULL 6 21 pthreadmutext gclientsmutex PTHREADMUTEXINITIALIZER 22 23 Imprime log no servidor 24 void serverlogconst struct sensormessage msg 25 printflog 26 printfs sensor in dd msg type msg coords 0 msg coords 1 27 printfmeasurement 4f msg measurement 28 fflushstdout 29 30 31 Envia msg para todos os clientes do mesmo tipo 32 void broadcastmessage const struct sensormessage msg 33 pthreadmutexlock gclientsmutex 34 clientnodet node gclients 35 while node 36 if strcmpnode type msg type 0 37 sendsensormessage node sockfd msg 38 39 node node next 40 41 pthreadmutexunlock gclientsmutex 42 43 44 Remove cliente da lista 45 void removeclient int sockfd 46 pthreadmutexlock gclientsmutex 47 clientnodet prev NULL 48 clientnodet curr gclients 49 while curr 50 if curr sockfd sockfd 51 if prev NULL 52 gclients curr next 53 else 54 prev next curr next 55 56 freecurr 57 pthreadmutexunlock gclientsmutex 58 return 59 60 prev curr 7 61 curr curr next 62 63 pthreadmutexunlock gclientsmutex 64 65 66 void clienthandler void arg 67 clientnodet client clientnodet arg 68 struct sensormessage msg 69 70 while 1 71 int ret recvsensormessage client sockfd msg 72 if ret 0 73 D e s c o n e x o 74 struct sensormessage exitmsg 75 memset exitmsg 0 sizeofexitmsg 76 strncpyexitmsgtype client type MAXTYPELEN 77 exitmsgcoords 0 client coords 0 78 exitmsgcoords 1 client coords 1 79 exitmsgmeasurement 10f R e m o o 80 81 Log 82 serverlog exitmsg 83 Broadcast 84 broadcastmessage exitmsg 85 86 closeclient sockfd 87 removeclientclient sockfd 88 pthreadexitNULL 89 90 91 pthreadmutexlock gclientsmutex 92 client coords 0 msgcoords 0 93 client coords 1 msgcoords 1 94 strncpyclient type msgtype MAXTYPELEN 95 client lastmeasurement msgmeasurement 96 pthreadmutexunlock gclientsmutex 97 98 serverlog msg 99 broadcastmessage msg 100 101 return NULL 8 102 103 104 int startserver const char version const char port 105 struct addrinfo hints res 106 int sockfd 107 int status 108 int yes 1 109 110 memset hints 0 sizeof hints 111 hintsaiflags AIPASSIVE 112 hintsaisocktype SOCKSTREAM 113 114 if strcmpversion v4 0 115 hintsaifamily AFINET 116 else if strcmpversion v6 0 117 hintsaifamily AFINET6 118 else 119 fprintfstderr Usage server v4v6 port 120 return 1 121 122 123 if status getaddrinfoNULL port hints res 0 124 fprintfstderr getaddrinfo error s gaistrerrorstatus 125 return 1 126 127 128 sockfd socketres aifamily res aisocktype res aiprotocol 129 if sockfd 0 130 perrorsocket 131 freeaddrinfo res 132 return 1 133 134 135 if setsockoptsockfd SOLSOCKET SOREUSEADDR yes sizeofint 0 136 perrorsetsockopt 137 closesockfd 138 freeaddrinfo res 9 139 return 1 140 141 142 if bindsockfd res aiaddr res aiaddrlen 0 143 perrorbind 144 closesockfd 145 freeaddrinfo res 146 return 1 147 148 149 freeaddrinfo res 150 151 if listensockfd 10 0 152 perrorlisten 153 closesockfd 154 return 1 155 156 157 return sockfd 158 159 160 int mainint argc char argv 161 if argc 3 162 fprintfstderr Usage server v4v6 port 163 exitEXITFAILURE 164 165 166 int serverfd startserverargv 1 argv 2 167 if serverfd 0 168 fprintfstderr Failed to start server 169 exitEXITFAILURE 170 171 172 printfServidor iniciado em s na porta s argv 1 argv 2 173 fflushstdout 174 175 while 1 176 struct sockaddrstorage clientaddr 177 socklent addrsize sizeofclientaddr 10 178 int newfd acceptserverfd struct sockaddr clientaddr addrsize 179 if newfd 0 180 perroraccept 181 continue 182 183 184 clientnodet newnode clientnodet calloc 1 sizeofclientnodet 185 newnode sockfd newfd 186 newnode next NULL 187 188 pthreadmutexlock gclientsmutex 189 newnode next gclients 190 gclients newnode 191 pthreadmutexunlock gclientsmutex 192 193 pthreadcreate newnode threadid NULL clienthandler void newnode 194 pthreaddetach newnode threadid 195 196 197 closeserverfd 198 return 0 199 54 Arquivo clientc Listing 4 clientc 1 2 Cliente TCP que representa um sensor Envia m e d i e s periodicamente ao servidor 3 e recebe as m e d i e s de outros sensores do mesmo tipo 4 5 6 include sensormessageh 7 include netdbh 8 include errnoh 9 include ctypeh 10 include pthreadh 11 11 12 define MAXSENSORS 100 13 14 typedef struct knownsensor 15 int x y 16 float measurement 17 int active 18 knownsensort 19 20 static knownsensort gknownSensors MAXSENSORS 21 static int gnumKnownSensors 0 22 pthreadmutext gsensormutex PTHREADMUTEXINITIALIZER 23 24 static char gtypeMAXTYPELEN 25 static int gcoords 2 26 static float gcurrentMeasurement 00f 27 static int gsockfd 1 28 29 static float gminVal 00f 30 static float gmaxVal 1000f 31 static int gsendInterval 5 32 33 int configuretype const char type 34 if strcmptype temperature 0 35 gminVal 200f 36 gmaxVal 400f 37 gsendInterval 5 38 return 0 39 else if strcmptype humidity 0 40 gminVal 100f 41 gmaxVal 900f 42 gsendInterval 7 43 return 0 44 else if strcmptype airquality 0 45 gminVal 150f 46 gmaxVal 300f 47 gsendInterval 10 48 return 0 49 50 return 1 51 52 53 float generateinitialmeasurement 12 54 srand unsigned inttimeNULL unsigned int getpid 55 float range gmaxVal gminVal 56 float randVal floatrand floatRANDMAX range gminVal 57 return randVal 58 59 60 float clampvaluefloat val float minv float maxv 61 if val minv return minv 62 if val maxv return maxv 63 return val 64 65 66 float applycorrection float current float remote double dist 67 float factor 01f 10f floatdist 10f 68 float diff remote current 69 float correction factor diff 70 float newVal current correction 71 return newVal 72 73 74 static int issamelocation int x int y 75 return x gcoords 0 y gcoords 1 76 77 78 static int findknownsensor int x int y 79 for int i 0 i gnumKnownSensors i 80 if gknownSensors i active 81 gknownSensors ix x 82 gknownSensors iy y 83 return i 84 85 86 return 1 87 88 89 static int addorupdatesensor int x int y float m 90 int idx findknownsensor x y 91 if idx 0 92 gknownSensors idx measurement m 93 gknownSensors idx active 1 13 94 return idx 95 else 96 if gnumKnownSensors MAXSENSORS 97 gknownSensors gnumKnownSensors x x 98 gknownSensors gnumKnownSensors y y 99 gknownSensors gnumKnownSensors measurement m 100 gknownSensors gnumKnownSensors active 1 101 gnumKnownSensors 102 return gnumKnownSensors 1 103 104 105 return 1 106 107 108 static void removesensorint x int y 109 int idx findknownsensor x y 110 if idx 0 111 gknownSensors idx active 0 112 113 114 115 static int getthreeclosest int out 3 116 int activeCount 0 117 double distArrayMAXSENSORS 118 int idxArrayMAXSENSORS 119 120 for int i 0 i gnumKnownSensors i 121 if gknownSensors i active 122 double d distanceeuclid gcoords 0 gcoords 1 123 gknownSensorsi x gknownSensors iy 124 distArrayactiveCount d 125 idxArrayactiveCount i 126 activeCount 127 128 129 if activeCount 0 return 0 130 14 131 for int i 0 i activeCount 1 i 132 for int j i 1 j activeCount j 133 if distArrayj distArrayi 134 double tmpD distArrayi 135 distArrayi distArrayj 136 distArrayj tmpD 137 int tmpI idxArrayi 138 idxArrayi idxArrayj 139 idxArrayj tmpI 140 141 142 143 144 int limit activeCount 3 activeCount 3 145 for int i 0 i limit i 146 outi idxArrayi 147 148 return limit 149 150 151 static void clientlogconst struct sensormessage msg const char action 152 printflog 153 printfs sensor in dd msg type msg coords 0 msg coords 1 154 printfmeasurement 4f msg measurement 155 printfaction s action 156 fflushstdout 157 158 159 void receiverthread void arg 160 voidarg 161 struct sensormessage msg 162 while 1 163 int ret recvsensormessage gsockfd msg 164 if ret 0 165 fprintfstderr Servidor desconectou ou erro no recv 166 closegsockfd 167 exit 1 168 169 170 pthreadmutexlock gsensormutex 15 171 172 if msgmeasurement 00f 173 removesensormsgcoords 0 msgcoords 1 174 clientlog msg removed 175 pthreadmutexunlock gsensormutex 176 continue 177 178 179 if issamelocation msgcoords 0 msgcoords 1 180 clientlog msg same location 181 pthreadmutexunlock gsensormutex 182 continue 183 184 185 addorupdatesensor msgcoords 0 msgcoords 1 msgmeasurement 186 187 int closeIdx 3 188 int nClose getthreeclosest closeIdx 189 190 int idx findknownsensor msgcoords 0 msg coords 1 191 int isNeighbor 0 192 for int i 0 i nClose i 193 if idx closeIdxi 194 isNeighbor 1 195 break 196 197 198 199 if isNeighbor 200 clientlog msg not neighbor 201 pthreadmutexunlock gsensormutex 202 continue 203 204 205 double dist distanceeuclid gcoords 0 gcoords 1 206 msgcoords 0 msg coords 1 207 float oldMeasurement gcurrentMeasurement 16 208 float newMeasurement applycorrection gcurrentMeasurement msgmeasurement dist 209 newMeasurement clampvaluenewMeasurement gminVal gmaxVal 210 float delta newMeasurement oldMeasurement 211 gcurrentMeasurement newMeasurement 212 213 char actionStr 64 214 snprintfactionStr sizeofactionStr correction of 4f delta 215 clientlog msg actionStr 216 217 pthreadmutexunlock gsensormutex 218 219 return NULL 220 221 222 int connectserver const char serverip const char port 223 struct addrinfo hints res p 224 int sockfd 1 225 int rv 226 227 memset hints 0 sizeof hints 228 hintsaisocktype SOCKSTREAM 229 hintsaifamily AFUNSPEC 230 231 if rv getaddrinfoserverip port hints res 0 232 fprintfstderr getaddrinfo s gaistrerrorrv 233 return 1 234 235 236 for p res p NULL p painext 237 sockfd socketpaifamily paisocktype p aiprotocol 238 if sockfd 0 239 continue 240 241 if connectsockfd paiaddr paiaddrlen 0 242 break 17 243 244 closesockfd 245 sockfd 1 246 247 248 freeaddrinfo res 249 return sockfd 250 251 252 static void printusage 253 fprintfstderr 254 Usage client serverip port type temperaturehumidityairquality coords x y 255 256 257 258 static int checkcoordinate const char c 259 int val atoic 260 if val 0 val 9 261 return 1 262 263 return val 264 265 266 int mainint argc char argv 267 if argc 7 268 fprintfstderr Error Invalid number of arguments 269 printusage 270 return 1 271 272 273 const char serverip argv 1 274 const char port argv 2 275 276 int i 277 int foundType 0 foundCoords 0 278 char sensorTypeBuf MAXTYPELEN 279 int x 1 y 1 280 281 for i 3 i argc i 282 if strcmpargvi type 0 18 283 if i 1 argc 284 strncpysensorTypeBuf argvi1 MAXTYPELEN 285 foundType 1 286 i 287 288 289 else if strcmpargvi coords 0 290 if i 2 argc 291 x checkcoordinate argvi1 292 y checkcoordinate argvi2 293 i 2 294 foundCoords 1 295 296 297 298 299 if foundType 300 fprintfstderr Error Expected type argument 301 printusage 302 return 1 303 304 if configuretype sensorTypeBuf 0 305 fprintfstderr Error Invalid sensor type 306 printusage 307 return 1 308 309 if foundCoords 310 fprintfstderr Error Expected coords argument 311 printusage 312 return 1 313 314 if x 0 y 0 315 fprintfstderr Error Coordinates must be in the range 09 316 printusage 317 return 1 318 319 320 strncpygtype sensorTypeBuf MAXTYPELEN 321 gcoords 0 x 19 322 gcoords 1 y 323 324 gsockfd connectserverserverip port 325 if gsockfd 0 326 fprintfstderr Erro ao conectar com o servidor 327 return 1 328 329 330 gcurrentMeasurement generateinitialmeasurement 331 332 pthreadt recvthread 333 pthreadcreate recvthread NULL receiverthread NULL 334 pthreaddetach recvthread 335 336 while 1 337 struct sensormessage msg 338 memset msg 0 sizeofmsg 339 strncpymsgtype gtype MAXTYPELEN 340 msgcoords 0 gcoords 0 341 msgcoords 1 gcoords 1 342 343 pthreadmutexlock gsensormutex 344 msgmeasurement gcurrentMeasurement 345 pthreadmutexunlock gsensormutex 346 347 if sendsensormessage gsockfd msg 0 348 fprintfstderr Erro ao enviar mensagem ao servidor 349 closegsockfd 350 exit 1 351 352 353 sleep gsendInterval 354 355 356 closegsockfd 357 return 0 358 20 6 Tratamento de Erros e Validacoes A aplicacao cliente verifica argumentos na seguinte ordem de prioridade 1 Quantidade de argumentos mınimo 7 2 type presenca e valor 3 Tipo de sensor invalido 4 coords presenca 5 Faixa de coordenadas 09 Sempre que ocorre um erro a mensagem Usage client e exibida 7 Exemplo de Funcionamento 71 Inicializacao do Servidor server v4 51511 Servidor iniciado em v4 na porta 51511 Acima o servidor esta rodando em IPv4 escutando na porta 51511 Figure 1 servidor 21 72 Inicializacao do Cliente Sensor de Temperatura client 127001 51511 type temperature coords 2 2 Este comando cria um sensor do tipo temperature posicionado em 22 Se por exemplo faltassem argumentos o cliente exibe Error Invalid number of arguments Usage client serverip port type temperaturehumidityairquality 73 Saıda no Servidor Quando esse primeiro cliente envia sua primeira medicao o servidor imprime log temperature sensor in 22 measurement 250000 podendo variar o valor inicial 74 Segundo Cliente Mesmo Tipo Rodamos client 127001 51511 type temperature coords 4 4 No 44 a saıda inicial do servidor podera ser log temperature sensor in 44 measurement 201352 Figure 2 saida 22 75 Logs no Cliente No primeiro cliente 22 assim que receber a medicao do sensor 44 sera impresso log temperature sensor in 44 measurement 201352 action correction of 01234 indica que o valor local foi corrigido em 01234 exemplo fictıcio 76 Agora same location Caso seja executado client 127001 51511 type temperature coords 2 2 enquanto ja existe outro sensor exatamente em 22 cada um recebe mensagens com log temperature sensor in 22 measurement 250000 action same location 77 Agora de not neighbor Se um terceiro sensor estiver a uma distˆancia muito maior que os 3 vizinhos mais proximos a acao exibida sera log temperature sensor in 99 measurement 350000 action not neighbor significando que o receptor descartou a correcao por ja ter 3 sensores mais proximos 78 Desconexao de um Sensor Se o cliente em 44 fechar com Ctrl C o servidor detecta e envia uma mensagem com measurement 10000 23 log temperature sensor in 44 measurement 10000 Todos os clientes do tipo temperature recebem isso e exibem log temperature sensor in 44 measurement 10000 action removed indicando que aquele sensor saiu do sistema 8 Conclusao Este projeto ilustra o uso de programacao em rede sockets POSIX bem como threads para lidar com multiplas conexoes simultˆaneas Tambem demonstra um minisistema de publishsubscribe baseado em tipos de sen sores aliando conceitos de redes de computadores e de Redes de Sensores Sem Fio RSSF Logs padronizados no servidor para cada medicao recebida Logs nos clientes indicando same location not neighbor correction of ou removed Atualizacao das leituras periodicamente sempre respeitando o limite maximo e mınimo do tipo de sensor 24
20
Rede de Computadores
UFMG
16
Rede de Computadores
UFMG
1
Rede de Computadores
UFMG
25
Rede de Computadores
UFMG
20
Rede de Computadores
UFMG
25
Rede de Computadores
UFMG
20
Rede de Computadores
UFMG
16
Rede de Computadores
UFMG
16
Rede de Computadores
UFMG
26
Rede de Computadores
UFMG
Texto de pré-visualização
Trabalho Prático 2 Redes de Sensores Sem Fio Entrega Individual Data de Entrega 08 de janeiro de 2025 as 2359 Introdução As Redes de Sensores Sem Fio RSSF representam uma tecnologia crucial para a coleta de dados em tempo real em ambientes diversos com aplicações como monitoramento ambiental automação industrial e até atuações dentro de seres vivos Essas redes consistem em pequenos dispositivos sensores geralmente distribuídos em uma área capazes de captar informações como temperatura umidade pressão etc Cada sensor se comunica sem fio com outros dispositivos ou diretamente com um servidor central permitindo a criação de sistemas distribuídos e escaláveis Nas figuras abaixo um exemplo de um diagrama de rede e um sensor ambos para situações embaixo dágua Imagem 1 Sala de Espera do jogo Among Us Para ilustrar o funcionamento de uma RSSF este trabalho prático tem como objetivo simular uma rede composta por três tipos de sensores espalhados em uma região delimitada Os sensores serão responsáveis por coletar e reportar informações de forma periódica Esses sensores se comunicarão com um servidor central utilizando um modelo publishsubscribe onde as mensagens serão enviadas a tópicos específicos de acordo com o tipo de sensor Clientes conectados a esses tópicos poderão receber os dados e atualizar suas medições com base na proximidade aos sensores Objetivo Você desenvolverá 2 programas para o sistema de salas de espera utilizando apenas as funcionalidades da biblioteca de sockets POSIX e a comunicação via protocolo TCP O código do servidor deverá utilizar múltiplas threads para a manutenção das múltiplas conexões As próximas seções detalham o que cada entidade servidor e cliente deve fazer Os objetivos deste trabalho são Desenvolver um servidor utilizando a interface de sockets na linguagem C Desenvolver um cliente utilizando a interface de sockets na linguagem C Permitir que múltiplos clientes sejam conectados ao servidor e que ele encaminhe as mensagens dos sensores Fazer com que os clientes reportem as medições de tempos em tempos e que atualizem suas medidas com base nos vizinhos Protocolo O protocolo de comunicação entre o cliente e o servidor será modelado de tal forma que as operações sejam representadas pela seguinte estrutura struct sensormessage char12 type int coords2 float measurement Abaixo descrição de cada uma das propriedades type Essa propriedade armazena o tipo do sensor Neste trabalho serão 3 diferentes temperature que vai medir a temperatura do ambiente humidity para sensores de umidade airquality para medir a qualidade do ar coords Essa propriedade representa as coordenadas do sensor no espaço Neste trabalho será considerado um grid 10x10 onde o primeiro valor do vetor representa em que linha o sensor está e o segundo a coluna measurement Já essa propriedade representa a medição de cada sensor que ele mantém e envia em cada intervalo de tempo além de atualizar conforme os vizinhos Inicialização O código do cliente deve ser executado passando como argumento as coordenadas Conforme mencionado anteriormente o espaço dos sensores é um grid 10x10 de forma que as coordenadas em cada eixo vão variar de 0 à 9 e devem ser passadas da seguinte forma client 127001 51511 type temperaturehumidityairquality coords x y O usuário pode passar parâmetros errados na hora de inicializar o cliente onde a ordem prioritária dos erros bem como as mensagens que devem ser exibidas são Tabela 1 Erros de inicialização e tratativas Descrição do Erro Exemplo Mensagem Faltando argumentos client 127001 51511 type temperature coords 5 Error Invalid number of arguments Argumento type faltando client 127001 51511 tipo temperature coords 5 7 Error Expected type argument Tipo de sensor não definido client 127001 51511 type pression coords 5 7 Error Invalid sensor type Argumento coords faltando client 127001 51511 type temperature pos 5 7 Error Expected coords argument Coordenadas fora do intervalo client 127001 51511 type temperature coords 10 7 Error Coordinates must be in the range 09 OBS Após cada mensagem de erro devese exibir também a seguinte mensagem padrão na linha de baixo Usage client serverip port type temperaturehumidityairquality coords x y Também erros que não estão listados como passar chars ao invés de inteiros não precisam ser tratados e não serão testados na avaliação Exemplo completo de erro e mensagem client 127001 51511 type temperature coords 5 Error Invalid number of arguments Usage client serverip port type tipos coords x y onde tipos temperaturehumidityairquality só para destacar que é na mesma linha Uma vez corretamente inicializado o sensor vai realizar sua medição que consiste em um valor aleatório no intervalo descrito na Tabela 2 A cada intervalo de tempo também descrito nesta tabela o cliente vai mandar uma mensagem para o servidor informando sua localização tipo e medição Tabela 2 Valores e Intervalos dos Sensores Tipo do sensor Intervalo das medições Intervalo entre mensagens Temperatura ºC 200 400 5 segundos Humidade 100 900 7 segundos Qualidade do ar μgm³ 150 300 10 segundos Funcionamento da Rede Após a inicialização dos valores o funcionamento do sistema segue uma abordagem baseada no padrão publishsubscribe Nesse sistema cada sensor já é inscrito no tópico correspondente ao seu tipo por exemplo temperature humidity ou airquality de forma que todas as mensagens enviadas pelos sensores de um determinado tipo são transmitidas para todos os sensores do mesmo tipo O servidor é responsável por gerenciar os tópicos garantindo que as mensagens sejam encaminhadas corretamente para os sensores interessados Os sensores enviam suas medições periodicamente para o tópico correspondente e o servidor as propaga para todos os sensores inscritos Cada sensor ao receber uma nova medição de outro sensor utiliza essa informação para corrigir sua própria medição com base na proximidade e na diferença entre os valores caso seja um dos três sensores mais próximos Isso significa que somente a primeira medição quanto o cliente é inicializado que escolhida aleatoriamente o restante são só ajustes nessa escolha A fórmula para atualizar a medição é dada da seguinte forma 𝑛𝑜𝑣𝑎𝑚𝑒𝑑𝑖çã𝑜 𝑚𝑒𝑑𝑖çã𝑜𝑎𝑡𝑢𝑎𝑙 0 1 1 𝑑 1 𝑚𝑒𝑑𝑖çã𝑜𝑟𝑒𝑚𝑜𝑡𝑎 𝑚𝑒𝑑𝑖çã𝑜𝑎𝑡𝑢𝑎𝑙 Onde novamedição é o novo valor do sensor após a correção mediçãoatual é o valor atual do sensor mediçãoremota é o valor enviado pelo sensor remoto d é a distância euclidiana entre o sensor atual e o sensor remoto 𝑑 𝑥1 𝑥2 2 𝑦1 𝑦2 2 Essa fórmula leva em conta tanto a diferença entre o valor do sensor que recebeu a mensagem e o valor atual quanto a proximidade entre os sensores Se após a atualização o valor corrigido ultrapassar o intervalo permitido Tabela 2 ele deve ser ajustado automaticamente para o limite mais próximo inferior ou superior Isso assegura que todas as medições permaneçam válidas dentro do contexto da aplicação Conforme já citado um aspecto crucial do sistema é o gerenciamento dos vizinhos mais próximos Cada sensor deve manter a informação de seus vizinhos pois vai atualizar sua medição somente com base nos três sensores mais próximos de sua posição descartando as medidas dos outros Manter todos os vizinhos e não só os 3 mais próximos é importante porque caso um dos sensores próximos saia do sistema o sensor atual deve identificar o próximo da fila para substituílo na lista de vizinhos mais próximos Essa feature é importante considerando as RSSF que têm que lidar constantemente com sensores saindo da rede eg sem bateria destruído pelo ambiente etc Descoberta Dinâmica de Sensores A descoberta de novos sensores no sistema é dinâmica Quando um novo sensor entra na rede ele pode começar recebendo e consequentemente utilizando para atualizar a sua medições de sensores que não necessariamente são seus vizinhos mais próximos considerando todos da rede devido à falta de conhecimento inicial sobre o ambiente Conforme novas mensagens são recebidas o sensor atual ajusta sua lista de vizinhos e passa a priorizar as medições dos mais próximos Para exemplificar considere o seguinte cenário um ambiente com 5 sensores do mesmo tipo e um novo sensor desse mesmo tipo entra no sistema Se ele receber mensagens na ordem do mais distante para o mais próximo ele realizará 5 atualizações até estabilizar com os três vizinhos mais próximos Se a ordem for do mais próximo para o mais distante apenas 3 atualizações serão realizadas pois ele estabiliza sua lista de vizinhos antes de processar as medições mais distantes Esse comportamento dinâmico ilustra o procedimento real de muitos sistemas em RSSF para descobrir seus vizinhos e a fórmula de atualização também considera esse caso ao considerar a distância e consequentemente diminuir a influência de sensores distantes Exibição das mensagens O servidor deve exibir todas as mensagens recebidas em um formato padronizado permitindo fácil rastreamento e depuração log type sensor in xy measurement measurement onde type Tipo do sensor temperature humidity ou airquality xy Coordenadas do sensor que enviou a mensagem measurement Valor da medição enviado Os clientes por sua vez vão exibir todas as mensagens que chegam para ele ou seja todas do mesmo tipo dele Isso inclui a deles mesmos já que não devem exibir nada ao enviar uma mensagem O formato de exibição é o mesmo do servidor mas com um campo a mais log type sensor in xy measurement measurement action status Esse último campo descreve o tratamento realizado daquela mensagem devendo ser exibido not neighbor Caso o sensor que recebeu considere que o emissor está muito longe para ser considerado vizinho e descarta a medição Essa ação só é possível caso o receptor já tenha três vizinhos e essa nova mensagem venha de um mais distante que esses três correction of value Caso onde o sensor é um vizinho e portanto é feita correção na medição O valor a ser exibido é o que vai ser corrigido da medição atual arredondado para quatro casas decimais Se negativo indicar com sinal na frente same location Caso o sensor emissor esteja na mesma célula que o receptor e portanto não deve ser considerada não é vizinho removed Caso em que o sensor saiu do sistema explicado no tópico abaixo Perceba que é possível sensores ocuparem o mesmo espaço do grid não bloqueamos isso na inicialização e como não passamos nenhum ID de cada sensor não temos como saber se a mensagem que chegou é a que o próprio sensor enviou ou de outro Assim para simplificar vamos considerar como não vizinho e descartar todas as medições da mesma célula que o sensor Obs Existe um no final do log que significa para adicionar mais uma quebra de linha para separar melhor os logs no terminal dando uma linha em branco entre eles Encerramento de um sensor Os clientes não vão receber nenhum input por parte do usuário Isso é proposital já que em Redes de Sensores Sem Fio os dispositivos são autônomos e descartáveis Assim para finalizar o sensor é necessário parar o processo do cliente Ctril C o que representa a destruiçãoinatividade do dispositivo O servidor por sua vez vai perceber que o cliente foi desconectado e deve exibir o log padrão mas com medida negativa 10000 e enviar essa medição para os sensores do mesmo tipo como se fosse uma medição normal desse sensor só que com valor negativo log type sensor in xy measurement 10000 Os clientes por sua vez devem interpretar que essa medição negativa representa que esse sensor não está mais disponível e devem removêlo de suas bases de dados Devem exibir a action como removed Exemplo de Execução Esta seção apresenta alguns exemplos de execuções do sistema A fim de facilitar a explicação as tabelas a seguir detalham o passo a passo das mensagens ao longo do tempo Nesse primeiro exemplo temos dois sensores do mesmo tipo se conectando no servidor inicialmente sem sensores Considere que o Sensor 1 teve medição inicial de 25 ºC e o segundo 20 ºC e que o envio e recebimento de mensagens é instantâneo Tempo 1 s Servidor Terminal 1 Terminal 2 T0 client 127001 51511 type temperature coords 2 2 T1 T2 client 127001 51511 type temperature coords 4 4 T3 T4 T5 log temperature sensor in 22 measurement 250000 log temperature sensor in 22 measurement 250000 action same location log temperature sensor in 22 measurement 250000 action correction of 01306 T6 T7 log temperature sensor in 44 measurement 201306 log temperature sensor in 44 measurement 201306 action correction of 01272 log temperature sensor in 44 measurement 201306 action same location T8 T9 T10 log temperature sensor in 22 measurement 248728 log temperature sensor in 22 measurement 248728 log temperature sensor in 22 measurement 248728 action same location action correction of 01239 T11 T12 log temperature sensor in 44 measurement 202542 log temperature sensor in 44 measurement 202545 action correction of 01206 log temperature sensor in 44 measurement 202545 action same location Abaixo um exemplo com 3 sensores um de cada tipo e entra um quarto sensor Considere as medidas iniciais como Sensor 1 Tipo temperature posição 22 medição inicial 250 Sensor 2 Tipo humidity posição 33 medição inicial 500 Sensor 3 Tipo airquality posição 11 medição inicial 220 Sensor 4 Tipo temperature posição 44 medição inicial 200 Tempo Servidor Terminal 1 Terminal 2 Terminal 3 Terminal 4 T0 client 127001 51511 type temperature coords 2 2 client 127001 51511 type humidity coords 3 3 client 127001 51511 type airquality coords 1 1 T1 T2 T3 client 127001 51511 type temperature coords 4 4 T4 T5 log temperature sensor in 22 log temperature sensor in 22 log temperature sensor in 22 measurement 250000 measurement 250000 action same location measurement 250000 action correction of 01306 T6 T7 log humidity sensor in 33 measurement 500000 log humidity sensor in 33 measurement 500000 action same location T8 log temperature sensor in 44 measurement 201306 log temperature sensor in 44 measurement 201306 action correction of 01272 log temperature sensor in 44 measurement 201306 action same location T9 T10 log temperature sensor in 22 measurement 248728 log airquality sensor in 11 measurement 220000 log temperature sensor in 22 measurement 248728 action same location log airquality sensor in 11 measurement 220000 action same location log temperature sensor in 22 measurement 248728 action correction of 01239 T11 T12 T13 log temperature sensor in 44 measurement 202545 log temperature sensor in 44 measurement 202545 action correction of 01206 log temperature sensor in 44 measurement 202545 action same location T14 log humidity sensor in 33 measurement 500000 log humidity sensor in 33 measurement 500000 action same location Por fim um exemplo em que um sensor se desconecta Considere os seguintes sensores Sensor 1 Tipo humidity posição 22 medição atual de 500 Sensor 2 Tipo humidity posição 23 medição atual de 550 Sensor 3 Tipo humidity posição 32 medição atual de 580 Sensor 4 Tipo humidity posição 33 medição atual de 520 Sensor 5 Tipo humidity posição 99 medição atual de 600 Cada um entrou no sistema com um segundo de diferença em ordem crescente ou seja primeiro o sensor 1 vai mandar mensagem depois o 2 etc Nesse exemplo os sensores já trocaram algumas mensagens de forma que os dispositivos 1 2 e 3 e 4 são vizinhos entre si Contudo quando o sensor 2 sai do sistema os outros consideram o 5 como um vizinho próximo Tempo Terminal 1 Terminal 2 Terminal 3 Terminal 4 Terminal 5 T0 log humidity sensor in 22 measurement 500000 action same location log humidity sensor in 22 measurement 500000 action correction of 02500 log humidity sensor in 22 measurement 500000 action correction of 01000 log humidity sensor in 22 measurement 500000 correction of 00828 log humidity sensor in 22 measurement 500000 action not neighbor T1 log humidity sensor in 23 measurement 547500 action correction of 02375 log humidity sensor in 23 measurement 547500 action action same location log humidity sensor in 23 measurement 547500 action correction of 02755 log humidity sensor in 23 measurement 547500 action correction of 01416 log humidity sensor in 23 measurement 547500 action correction of 00514 T2 log humidity sensor in 32 measurement 483755 action correction of 00931 log humidity sensor in 32 measurement 483755 action correction of 02640 log humidity sensor in 32 measurement 483755 action same location log humidity sensor in 32 measurement 483755 action correction of 01842 log humidity sensor in 32 measurement 483755 action correction of 01132 T3 log humidity sensor in 33 measurement 518746 action correction of 00717 log humidity sensor in 33 measurement 518746 action correction of 01306 log humidity sensor in 33 measurement 518746 action correction of 01750 log humidity sensor in 33 measurement 518746 action same location log humidity sensor in 33 measurement 518746 action correction of 00839 T4 log humidity sensor in 99 measurement 597515 action not neighbor log humidity sensor in 99 measurement 597515 action not neighbor log humidity sensor in 99 measurement 597515 action not neighbor log humidity sensor in 99 measurement 597515 action not neighbor log humidity sensor in 99 measurement 597515 action same location T5 T6 log humidity sensor in 23 measurement 10000 action removed Ctril C Cliente se desconecta Servidor manda mensagem com medida 10000 log humidity sensor in 23 measurement 10000 action removed log humidity sensor in 23 measurement 10000 action removed log humidity sensor in 23 measurement 10000 action removed T7 log humidity sensor in 22 measurement 502161 action same location log humidity sensor in 22 measurement 502161 action correction of 00833 log humidity sensor in 22 measurement 502161 action correction of 00687 log humidity sensor in 22 measurement 502161 action correction of 00875 T8 T9 log humidity sensor in 32 measurement 486337 action correction of 00791 log humidity sensor in 32 measurement 486337 action same location log humidity sensor in 32 measurement 486337 action correction of 01586 log humidity sensor in 32 measurement 486337 action correction of 01079 T10 log humidity sensor in 33 measurement 516473 action correction of 00626 log humidity sensor in 33 measurement 516473 action correction of 01507 log humidity sensor in 33 measurement 516473 action same location log humidity sensor in 33 measurement 516473 action correction of 00834 T11 log humidity sensor in 99 measurement 594727 action correction of 00851 log humidity sensor in 99 measurement 594727 action correction of 01046 log humidity sensor in 99 measurement 594727 action correction of 00825 log humidity sensor in 99 measurement 594727 action same location Detalhes de implementação Gerenciamento de Sensores O servidor será responsável por manter o registro de todos os sensores conectados incluindo suas coordenadas e tipo Os sensores devem manter a lista dos vizinhos mais próximos Caso um vizinho caia o sensor deve atualizar sua lista promovendo o próximo da fila à posição de vizinho próxmo Tipos de Sensores Apenas três tipos de sensores serão aceitos temperature humidity e airquality Qualquer tipo diferente deve resultar em um erro e impedir a execução do cliente Coordenadas dos Sensores As coordenadas dos sensores devem ser especificadas ao iniciar o cliente e precisam estar dentro do intervalo 0 9 Caso as coordenadas estejam fora do intervalo ou não sejam numéricas o cliente deve exibir uma mensagem de erro e não iniciar Mensagens e Tópicos Cada tipo de sensor possui um tópico exclusivo no qual serão publicadas e recebidas as mensagens Mensagens de sensores do mesmo tipo devem ser encaminhadas apenas para outros sensores do mesmo tipo Atualização de Medições As medições iniciais são aleatórias dentro dos intervalos definidos mas todas as atualizações subsequentes devem usar a fórmula de correção com base nos vizinhos mais próximos Apenas os três vizinhos mais próximos serão usados para corrigir medições Se não houver vizinhos a medição fica sempre a mesma Novos Sensores Sensores que entram dinamicamente no sistema podem usar medições de outros sensores fora de sua vizinhança real até descobrirem os vizinhos mais próximos Limites e Formatação As medições devem ser exibidas com até 4 casas decimais As coordenadas dos sensores no log devem estar no formato xy Desempenho e Limites Serão testados até 12 sensores simultâneos Certifiquese de que o sistema funcione corretamente dentro deste limite Erros e Validações Mensagens de erro específicas devem ser exibidas para parâmetros inválidos tipo ou coordenadas impedindo o cliente de iniciar Sensores sobrepostos Mais de um sensor podem ocupar o mesmo espaço no sistema de tipos iguais ou diferentes As medições da mesma localização do sensor não são usadas para atualizar as medições e nem são consideradas vizinhos Ou seja se só houver sensores num mesmo local ninguém atualiza as medições Desenvolvimento O projeto requer a implementação de dois componentes essenciais um servidor e um cliente ambos baseados no protocolo TCP É crucial garantir que ambos os componentes sejam compatíveis tanto com o IPv4 quanto com o IPv6 proporcionando flexibilidade na escolha do endereço IP Para configurar o servidor corretamente este deve ser capaz de receber seguindo rigorosamente essa ordem o tipo de endereço desejado v4 para IPv4 ou v6 para IPv6 e um número de porta especificado na linha de comando Recomendase a utilização da porta 51511 para manter a padronização do projeto Da mesma forma os clientes precisam receber também rigorosamente nessa ordem o endereço IP do servidor e o número de porta para estabelecer a conexão com sucesso Certifiquese de que ambos os componentes sejam configurados de acordo com essas diretrizes para uma integração eficaz e a comunicação adequada entre servidor e cliente A seguir um exemplo de execução dos programas em dois terminais distintos IPv4 no terminal 1 server v4 51511 no terminal 2 client 127001 51511 type temperature coords 1 1 no terminal 3 client 127001 51511 type airquality coords 2 2 IPv6 no terminal 1 server v6 51511 no terminal 2 client 1 51511 type humidity coords 5 6 no terminal 3 client 1 51511 type humidity coords 6 5 Sobre Threads O uso de threads em servidores é uma abordagem eficiente para lidar com múltiplas conexões simultâneas Em um servidor multithread cada cliente conectado é gerenciado por uma thread separada permitindo que o servidor processe várias requisições de forma paralela Essa arquitetura tem várias vantagens com talvez a principal de evitar que a execução de uma operação mais demorada por um cliente bloqueie o atendimento de outros garantindo maior responsividade do sistema No contexto deste trabalho prático o servidor será responsável por criar uma nova thread para cada cliente que se conecta Cada thread atuará de forma independente lidando com as mensagens daquele cliente Ao mesmo tempo o servidor principal continuará rodando em sua thread principal aceitando novas conexões sem interrupções Essa abordagem permite manter um fluxo contínuo de comunicação entre os sensores e o servidor assegurando que todas as mensagens sejam tratadas adequadamente mesmo em cenários com vários sensores conectados simultaneamente Para aqueles que não conhecem ou desejam relembrar esses conceitos recomendo essa playlist em especial os vídeos 5 6 e 7 Materiais para Consulta e Dicas Capítulo 2 e 3 do livro sobre programação com sockets disponibilizado no Moodle Playlist de programação com sockets do professor Ítalo Cunha O guia de programação em rede do Beej httpbeejusguidebgnet tem bons exemplos de como organizar um servidor Implemente o trabalho por partes Por exemplo implemente o tratamento das múltiplas conexões depois crie os formatos das mensagens e por fim trate os tópicos e as especifidades Procure resolver os desafios da maneira mais simples possível Avaliação O trabalho deve ser realizado individualmente e deve ser implementado com a linguagem de programação C não sendo permitida a utilização de C utilizando somente a biblioteca padrão interface POSIX de sockets de redes Deve ser possível executar seu programa no sistema operacional Linux e não deve utilizar bibliotecas Windows como o winsock Seu programa deve interoperar com qualquer outro programa implementando o mesmo protocolo você pode testar com as implementações dos seus colegas Procure escrever seu código de maneira clara com comentários pontuais e bem identados Isto facilita a correção dos monitores e tem impacto positivo na avaliação Correção Semiautomática Seu servidor será corrigido de forma semiautomática por uma bateria de testes Cada teste verifica uma funcionalidade específica do servidor Para a correção os seguintes testes serão realizados com IPv4 e IPv6 Conexão de múltiplos clientes 10 Gerenciamento correto dos vizinhos descoberta dinâmica 15 Encaminhamento correto das mensagens para os clientes 15 Atualização correta das medições 15 Impressão correta das mensagens 10 Fechamento de conexão 10 Tratativa dos erros 5 Documentação 20 Informações importantes Cada aluno deve entregar documentação em PDF de até 4 páginas duas folhas sem capa utilizando fonte Arial tamanho 12 e figuras de tamanho adequado ao tamanho da fonte A documentação deve discutir desafios dificuldades e imprevistos do projeto bem como as soluções adotadas para os problemas Atenção Será dado grande importância a parte da discussão dos desafios encontrados pois as dificuldades ao longo do projeto sempre existem A documentação corresponde a 20 dos pontos do trabalho mas só será considerada para as funcionalidades implementadas corretamente Será utilizado um sistema para detecção de código repetido portanto não é admitido cola de trabalhos Será adotada média harmônica entre as notas da documentação e da execução o que implica que a nota final será 0 se uma das partes não for apresentada Cada aluno deve entregar além da documentação o código fonte em C e um Makefile para compilação do programa Instruções para submissão e compatibilidade com o sistema de correção semiautomática O Makefile deve compilar o cliente em um binário chamado client e o servidor em um binário chamado server dentro de uma pasta chamada bin na raiz do projeto Seu programa deve ser compilado ao se executar apenas o comando make ou seja sem a necessidade de parâmetros adicionais A entrega deve ser feita no formato ZIP com o nome seguindo o seguinte padrão TP2MATRICULAzip Desconto de Nota por Atraso Os trabalhos poderão ser entregues até a meianoite do dia especificado para a entrega Não serão aceitos trabalhos com atraso Relatorio do Projeto de Salas de Espera em Redes de Sensores January 18 2025 1 Introducao Foi descrito nesse documento um desenvolvimento de um sistema de salas de espera para Redes de Sensores Sem Fio RSSF utilizando sockets POSIX sobre TCP O sistema e composto por dois programas em linguagem C um servidor multithread e um cliente que representa um sensor Os clientes podem ser de trˆes tipos temperature humidity e air quality e enviam suas leituras de forma periodica ao servidor O servidor e responsavel por gerenciar todos os sensores conectados iden tificando o tipo de cada um que atua como um topico de publishsubscribe Assim todas as mensagens publicadas pelos sensores de um determinado tipo sao encaminhadas para todos os sensores desse mesmo tipo 2 Objetivos Os objetivos principais deste trabalho sao Desenvolver um servidor que gerencie multiplas conexoes de clientes por meio de threads Garantir que o servidor propague as leituras de sensores do mesmo tipo para todos os clientes que pertencam ao mesmo topico tipo Fazer com que os clientes reportem as medicoes periodicamente e atu alizem suas leituras usando as informacoes de ate trˆes vizinhos mais proximos conforme distˆancia euclidiana Demonstrar o tratamento correto de erros de inicializacao no cliente e de desconexao de sensores 1 3 Descricao do Problema Em Redes de Sensores Sem Fio RSSF cada dispositivo sensor reporta leituras do ambiente temperatura umidade ou qualidade do ar em um grid de tamanho 1010 no qual as coordenadas variam de 0 a 9 Sempre que um sensor recebe a leitura de outro sensor do mesmo tipo ele verifica se o emissor esta entre os trˆes vizinhos mais proximos em termos de distˆancia euclidiana e caso sim aplica uma formula de correcao em sua propria medicao 31 Formula de Correcao A correcao e dada por nova medicao medicao atual01 1 d 1medicao remotamedicao atual onde d e a distˆancia euclidiana entre os dois sensores no grid medicao remota e a leitura recebida medicao atual e a leitura do sensor local antes da correcao 4 Visao Geral da Solucao A solucao se baseia em duas aplicacoes server e client 41 Servidor Cria um socket TCP compatıvel com IPv4 ou IPv6 Fica em listen aceitando conexoes de clientes Para cada cliente conectado cria uma nova thread que fica responsavel por receber as mensagens desse cliente Ao receber uma mensagem sensor message o servidor 1 Imprime em seu console o log do sensor 2 Reenvia a mensagem a todos os clientes do mesmo tipo topico Se o cliente encerrar a conexao repentinamente via CtrlC o servi dor 2 1 Identifica a desconexao 2 Gera uma mensagem com measurement 10000 indicando que o sensor saiu do sistema 3 Faz o broadcast dessa mensagem para os clientes do mesmo tipo 42 Cliente Sensor Conectase ao servidor via TCP fornecendo IP do servidor pode ser IPv4 ou IPv6 Porta de conexao por exemplo 51511 Tipo do sensor temperature humidity air quality Coordenadas x y do grid Gera sua medicao inicial de forma aleatoria dentro dos intervalos es pecificados temperature entre 200 e 400 humidity entre 100 e 900 air quality entre 150 e 300 Periodicamente envia sua propria medicao ao servidor temperature a cada 5 segundos humidity a cada 7 segundos air quality a cada 10 segundos Recebe assıncronamente numa thread dedicada as mensagens de outros sensores do mesmo tipo Se a mensagem vier de um sensor que nao seja vizinho entre os 3 mais proximos exibe action not neighbor Se vier de um sensor na mesma celula x y exibe action same location Caso o sensor seja um dos 3 mais proximos aplica a formula de correcao exibe action correction of Em caso de mensagem com measurement 10000 exibe action removed e remove o sensor do cadastro local 3 5 Estrutura do Codigo Para simplificar todo o codigo esta a seguir em blocos lstlisting 51 Arquivo sensor messageh Listing 1 sensormessageh 1 ifndef SENSORMESSAGEH 2 define SENSORMESSAGEH 3 4 include stdioh 5 include stdlibh 6 include stringh 7 include unistdh 8 include arpaineth 9 include syssocketh 10 include pthreadh 11 include mathh 12 include timeh 13 14 define MAXTYPELEN 12 15 16 struct sensormessage 17 char typeMAXTYPELEN temperature humidity ou airquality 18 int coords 2 coords 0 x coords 1 y 19 float measurement valor da m e d i o 20 21 22 ssizet readallint sockfd void buffer sizet size 23 ssizet writeallint sockfd const void buffer sizet size 24 int sendsensormessage int sockfd const struct sensormessage msg 25 int recvsensormessage int sockfd struct sensormessage msg 26 double distanceeuclid int x1 int y1 int x2 int y2 27 28 endif 4 52 Arquivo sensor messagec Listing 2 sensormessagec 1 include sensormessageh 2 3 ssizet readallint sockfd void buffer sizet size 4 sizet bytesRead 0 5 char buf char buffer 6 while bytesRead size 7 ssizet result readsockfd buf bytesRead size bytesRead 8 if result 0 9 return result Erro ou c o n e x o fechada 10 11 bytesRead result 12 13 return ssizet bytesRead 14 15 16 ssizet writeallint sockfd const void buffer sizet size 17 sizet bytesSent 0 18 const char buf const char buffer 19 while bytesSent size 20 ssizet result writesockfd buf bytesSent size bytesSent 21 if result 0 22 return result Erro 23 24 bytesSent result 25 26 return ssizet bytesSent 27 28 29 int sendsensormessage int sockfd const struct sensormessage msg 30 ssizet n writeallsockfd msg sizeofstruct sensormessage 31 return n sizeofstruct sensormessage 0 1 32 33 5 34 int recvsensormessage int sockfd struct sensormessage msg 35 ssizet n readallsockfd msg sizeofstruct sensormessage 36 if n 0 return 1 37 if n ssizetsizeofstruct sensormessage return 1 38 return 0 39 40 41 double distanceeuclid int x1 int y1 int x2 int y2 42 double dx doublex1 x2 43 double dy doubley1 y2 44 return sqrtdx dx dy dy 45 53 Arquivo serverc Listing 3 serverc 1 2 Servidor TCP IPv4IPv6 que recebe mensagens de sensores e faz broadcast 3 para todos os sensores do mesmo tipo gerenciando m l t i p l a s c o n e x e s com threads 4 5 6 include sensormessageh 7 include netdbh 8 include errnoh 9 10 Estrutura para manter i n f o r m a e s de cada cliente conectado 11 typedef struct clientnode 12 int sockfd 13 pthreadt threadid 14 char typeMAXTYPELEN 15 int coords 2 16 float lastmeasurement 17 struct clientnode next 18 clientnodet 19 20 clientnodet gclients NULL 6 21 pthreadmutext gclientsmutex PTHREADMUTEXINITIALIZER 22 23 Imprime log no servidor 24 void serverlogconst struct sensormessage msg 25 printflog 26 printfs sensor in dd msg type msg coords 0 msg coords 1 27 printfmeasurement 4f msg measurement 28 fflushstdout 29 30 31 Envia msg para todos os clientes do mesmo tipo 32 void broadcastmessage const struct sensormessage msg 33 pthreadmutexlock gclientsmutex 34 clientnodet node gclients 35 while node 36 if strcmpnode type msg type 0 37 sendsensormessage node sockfd msg 38 39 node node next 40 41 pthreadmutexunlock gclientsmutex 42 43 44 Remove cliente da lista 45 void removeclient int sockfd 46 pthreadmutexlock gclientsmutex 47 clientnodet prev NULL 48 clientnodet curr gclients 49 while curr 50 if curr sockfd sockfd 51 if prev NULL 52 gclients curr next 53 else 54 prev next curr next 55 56 freecurr 57 pthreadmutexunlock gclientsmutex 58 return 59 60 prev curr 7 61 curr curr next 62 63 pthreadmutexunlock gclientsmutex 64 65 66 void clienthandler void arg 67 clientnodet client clientnodet arg 68 struct sensormessage msg 69 70 while 1 71 int ret recvsensormessage client sockfd msg 72 if ret 0 73 D e s c o n e x o 74 struct sensormessage exitmsg 75 memset exitmsg 0 sizeofexitmsg 76 strncpyexitmsgtype client type MAXTYPELEN 77 exitmsgcoords 0 client coords 0 78 exitmsgcoords 1 client coords 1 79 exitmsgmeasurement 10f R e m o o 80 81 Log 82 serverlog exitmsg 83 Broadcast 84 broadcastmessage exitmsg 85 86 closeclient sockfd 87 removeclientclient sockfd 88 pthreadexitNULL 89 90 91 pthreadmutexlock gclientsmutex 92 client coords 0 msgcoords 0 93 client coords 1 msgcoords 1 94 strncpyclient type msgtype MAXTYPELEN 95 client lastmeasurement msgmeasurement 96 pthreadmutexunlock gclientsmutex 97 98 serverlog msg 99 broadcastmessage msg 100 101 return NULL 8 102 103 104 int startserver const char version const char port 105 struct addrinfo hints res 106 int sockfd 107 int status 108 int yes 1 109 110 memset hints 0 sizeof hints 111 hintsaiflags AIPASSIVE 112 hintsaisocktype SOCKSTREAM 113 114 if strcmpversion v4 0 115 hintsaifamily AFINET 116 else if strcmpversion v6 0 117 hintsaifamily AFINET6 118 else 119 fprintfstderr Usage server v4v6 port 120 return 1 121 122 123 if status getaddrinfoNULL port hints res 0 124 fprintfstderr getaddrinfo error s gaistrerrorstatus 125 return 1 126 127 128 sockfd socketres aifamily res aisocktype res aiprotocol 129 if sockfd 0 130 perrorsocket 131 freeaddrinfo res 132 return 1 133 134 135 if setsockoptsockfd SOLSOCKET SOREUSEADDR yes sizeofint 0 136 perrorsetsockopt 137 closesockfd 138 freeaddrinfo res 9 139 return 1 140 141 142 if bindsockfd res aiaddr res aiaddrlen 0 143 perrorbind 144 closesockfd 145 freeaddrinfo res 146 return 1 147 148 149 freeaddrinfo res 150 151 if listensockfd 10 0 152 perrorlisten 153 closesockfd 154 return 1 155 156 157 return sockfd 158 159 160 int mainint argc char argv 161 if argc 3 162 fprintfstderr Usage server v4v6 port 163 exitEXITFAILURE 164 165 166 int serverfd startserverargv 1 argv 2 167 if serverfd 0 168 fprintfstderr Failed to start server 169 exitEXITFAILURE 170 171 172 printfServidor iniciado em s na porta s argv 1 argv 2 173 fflushstdout 174 175 while 1 176 struct sockaddrstorage clientaddr 177 socklent addrsize sizeofclientaddr 10 178 int newfd acceptserverfd struct sockaddr clientaddr addrsize 179 if newfd 0 180 perroraccept 181 continue 182 183 184 clientnodet newnode clientnodet calloc 1 sizeofclientnodet 185 newnode sockfd newfd 186 newnode next NULL 187 188 pthreadmutexlock gclientsmutex 189 newnode next gclients 190 gclients newnode 191 pthreadmutexunlock gclientsmutex 192 193 pthreadcreate newnode threadid NULL clienthandler void newnode 194 pthreaddetach newnode threadid 195 196 197 closeserverfd 198 return 0 199 54 Arquivo clientc Listing 4 clientc 1 2 Cliente TCP que representa um sensor Envia m e d i e s periodicamente ao servidor 3 e recebe as m e d i e s de outros sensores do mesmo tipo 4 5 6 include sensormessageh 7 include netdbh 8 include errnoh 9 include ctypeh 10 include pthreadh 11 11 12 define MAXSENSORS 100 13 14 typedef struct knownsensor 15 int x y 16 float measurement 17 int active 18 knownsensort 19 20 static knownsensort gknownSensors MAXSENSORS 21 static int gnumKnownSensors 0 22 pthreadmutext gsensormutex PTHREADMUTEXINITIALIZER 23 24 static char gtypeMAXTYPELEN 25 static int gcoords 2 26 static float gcurrentMeasurement 00f 27 static int gsockfd 1 28 29 static float gminVal 00f 30 static float gmaxVal 1000f 31 static int gsendInterval 5 32 33 int configuretype const char type 34 if strcmptype temperature 0 35 gminVal 200f 36 gmaxVal 400f 37 gsendInterval 5 38 return 0 39 else if strcmptype humidity 0 40 gminVal 100f 41 gmaxVal 900f 42 gsendInterval 7 43 return 0 44 else if strcmptype airquality 0 45 gminVal 150f 46 gmaxVal 300f 47 gsendInterval 10 48 return 0 49 50 return 1 51 52 53 float generateinitialmeasurement 12 54 srand unsigned inttimeNULL unsigned int getpid 55 float range gmaxVal gminVal 56 float randVal floatrand floatRANDMAX range gminVal 57 return randVal 58 59 60 float clampvaluefloat val float minv float maxv 61 if val minv return minv 62 if val maxv return maxv 63 return val 64 65 66 float applycorrection float current float remote double dist 67 float factor 01f 10f floatdist 10f 68 float diff remote current 69 float correction factor diff 70 float newVal current correction 71 return newVal 72 73 74 static int issamelocation int x int y 75 return x gcoords 0 y gcoords 1 76 77 78 static int findknownsensor int x int y 79 for int i 0 i gnumKnownSensors i 80 if gknownSensors i active 81 gknownSensors ix x 82 gknownSensors iy y 83 return i 84 85 86 return 1 87 88 89 static int addorupdatesensor int x int y float m 90 int idx findknownsensor x y 91 if idx 0 92 gknownSensors idx measurement m 93 gknownSensors idx active 1 13 94 return idx 95 else 96 if gnumKnownSensors MAXSENSORS 97 gknownSensors gnumKnownSensors x x 98 gknownSensors gnumKnownSensors y y 99 gknownSensors gnumKnownSensors measurement m 100 gknownSensors gnumKnownSensors active 1 101 gnumKnownSensors 102 return gnumKnownSensors 1 103 104 105 return 1 106 107 108 static void removesensorint x int y 109 int idx findknownsensor x y 110 if idx 0 111 gknownSensors idx active 0 112 113 114 115 static int getthreeclosest int out 3 116 int activeCount 0 117 double distArrayMAXSENSORS 118 int idxArrayMAXSENSORS 119 120 for int i 0 i gnumKnownSensors i 121 if gknownSensors i active 122 double d distanceeuclid gcoords 0 gcoords 1 123 gknownSensorsi x gknownSensors iy 124 distArrayactiveCount d 125 idxArrayactiveCount i 126 activeCount 127 128 129 if activeCount 0 return 0 130 14 131 for int i 0 i activeCount 1 i 132 for int j i 1 j activeCount j 133 if distArrayj distArrayi 134 double tmpD distArrayi 135 distArrayi distArrayj 136 distArrayj tmpD 137 int tmpI idxArrayi 138 idxArrayi idxArrayj 139 idxArrayj tmpI 140 141 142 143 144 int limit activeCount 3 activeCount 3 145 for int i 0 i limit i 146 outi idxArrayi 147 148 return limit 149 150 151 static void clientlogconst struct sensormessage msg const char action 152 printflog 153 printfs sensor in dd msg type msg coords 0 msg coords 1 154 printfmeasurement 4f msg measurement 155 printfaction s action 156 fflushstdout 157 158 159 void receiverthread void arg 160 voidarg 161 struct sensormessage msg 162 while 1 163 int ret recvsensormessage gsockfd msg 164 if ret 0 165 fprintfstderr Servidor desconectou ou erro no recv 166 closegsockfd 167 exit 1 168 169 170 pthreadmutexlock gsensormutex 15 171 172 if msgmeasurement 00f 173 removesensormsgcoords 0 msgcoords 1 174 clientlog msg removed 175 pthreadmutexunlock gsensormutex 176 continue 177 178 179 if issamelocation msgcoords 0 msgcoords 1 180 clientlog msg same location 181 pthreadmutexunlock gsensormutex 182 continue 183 184 185 addorupdatesensor msgcoords 0 msgcoords 1 msgmeasurement 186 187 int closeIdx 3 188 int nClose getthreeclosest closeIdx 189 190 int idx findknownsensor msgcoords 0 msg coords 1 191 int isNeighbor 0 192 for int i 0 i nClose i 193 if idx closeIdxi 194 isNeighbor 1 195 break 196 197 198 199 if isNeighbor 200 clientlog msg not neighbor 201 pthreadmutexunlock gsensormutex 202 continue 203 204 205 double dist distanceeuclid gcoords 0 gcoords 1 206 msgcoords 0 msg coords 1 207 float oldMeasurement gcurrentMeasurement 16 208 float newMeasurement applycorrection gcurrentMeasurement msgmeasurement dist 209 newMeasurement clampvaluenewMeasurement gminVal gmaxVal 210 float delta newMeasurement oldMeasurement 211 gcurrentMeasurement newMeasurement 212 213 char actionStr 64 214 snprintfactionStr sizeofactionStr correction of 4f delta 215 clientlog msg actionStr 216 217 pthreadmutexunlock gsensormutex 218 219 return NULL 220 221 222 int connectserver const char serverip const char port 223 struct addrinfo hints res p 224 int sockfd 1 225 int rv 226 227 memset hints 0 sizeof hints 228 hintsaisocktype SOCKSTREAM 229 hintsaifamily AFUNSPEC 230 231 if rv getaddrinfoserverip port hints res 0 232 fprintfstderr getaddrinfo s gaistrerrorrv 233 return 1 234 235 236 for p res p NULL p painext 237 sockfd socketpaifamily paisocktype p aiprotocol 238 if sockfd 0 239 continue 240 241 if connectsockfd paiaddr paiaddrlen 0 242 break 17 243 244 closesockfd 245 sockfd 1 246 247 248 freeaddrinfo res 249 return sockfd 250 251 252 static void printusage 253 fprintfstderr 254 Usage client serverip port type temperaturehumidityairquality coords x y 255 256 257 258 static int checkcoordinate const char c 259 int val atoic 260 if val 0 val 9 261 return 1 262 263 return val 264 265 266 int mainint argc char argv 267 if argc 7 268 fprintfstderr Error Invalid number of arguments 269 printusage 270 return 1 271 272 273 const char serverip argv 1 274 const char port argv 2 275 276 int i 277 int foundType 0 foundCoords 0 278 char sensorTypeBuf MAXTYPELEN 279 int x 1 y 1 280 281 for i 3 i argc i 282 if strcmpargvi type 0 18 283 if i 1 argc 284 strncpysensorTypeBuf argvi1 MAXTYPELEN 285 foundType 1 286 i 287 288 289 else if strcmpargvi coords 0 290 if i 2 argc 291 x checkcoordinate argvi1 292 y checkcoordinate argvi2 293 i 2 294 foundCoords 1 295 296 297 298 299 if foundType 300 fprintfstderr Error Expected type argument 301 printusage 302 return 1 303 304 if configuretype sensorTypeBuf 0 305 fprintfstderr Error Invalid sensor type 306 printusage 307 return 1 308 309 if foundCoords 310 fprintfstderr Error Expected coords argument 311 printusage 312 return 1 313 314 if x 0 y 0 315 fprintfstderr Error Coordinates must be in the range 09 316 printusage 317 return 1 318 319 320 strncpygtype sensorTypeBuf MAXTYPELEN 321 gcoords 0 x 19 322 gcoords 1 y 323 324 gsockfd connectserverserverip port 325 if gsockfd 0 326 fprintfstderr Erro ao conectar com o servidor 327 return 1 328 329 330 gcurrentMeasurement generateinitialmeasurement 331 332 pthreadt recvthread 333 pthreadcreate recvthread NULL receiverthread NULL 334 pthreaddetach recvthread 335 336 while 1 337 struct sensormessage msg 338 memset msg 0 sizeofmsg 339 strncpymsgtype gtype MAXTYPELEN 340 msgcoords 0 gcoords 0 341 msgcoords 1 gcoords 1 342 343 pthreadmutexlock gsensormutex 344 msgmeasurement gcurrentMeasurement 345 pthreadmutexunlock gsensormutex 346 347 if sendsensormessage gsockfd msg 0 348 fprintfstderr Erro ao enviar mensagem ao servidor 349 closegsockfd 350 exit 1 351 352 353 sleep gsendInterval 354 355 356 closegsockfd 357 return 0 358 20 6 Tratamento de Erros e Validacoes A aplicacao cliente verifica argumentos na seguinte ordem de prioridade 1 Quantidade de argumentos mınimo 7 2 type presenca e valor 3 Tipo de sensor invalido 4 coords presenca 5 Faixa de coordenadas 09 Sempre que ocorre um erro a mensagem Usage client e exibida 7 Exemplo de Funcionamento 71 Inicializacao do Servidor server v4 51511 Servidor iniciado em v4 na porta 51511 Acima o servidor esta rodando em IPv4 escutando na porta 51511 Figure 1 servidor 21 72 Inicializacao do Cliente Sensor de Temperatura client 127001 51511 type temperature coords 2 2 Este comando cria um sensor do tipo temperature posicionado em 22 Se por exemplo faltassem argumentos o cliente exibe Error Invalid number of arguments Usage client serverip port type temperaturehumidityairquality 73 Saıda no Servidor Quando esse primeiro cliente envia sua primeira medicao o servidor imprime log temperature sensor in 22 measurement 250000 podendo variar o valor inicial 74 Segundo Cliente Mesmo Tipo Rodamos client 127001 51511 type temperature coords 4 4 No 44 a saıda inicial do servidor podera ser log temperature sensor in 44 measurement 201352 Figure 2 saida 22 75 Logs no Cliente No primeiro cliente 22 assim que receber a medicao do sensor 44 sera impresso log temperature sensor in 44 measurement 201352 action correction of 01234 indica que o valor local foi corrigido em 01234 exemplo fictıcio 76 Agora same location Caso seja executado client 127001 51511 type temperature coords 2 2 enquanto ja existe outro sensor exatamente em 22 cada um recebe mensagens com log temperature sensor in 22 measurement 250000 action same location 77 Agora de not neighbor Se um terceiro sensor estiver a uma distˆancia muito maior que os 3 vizinhos mais proximos a acao exibida sera log temperature sensor in 99 measurement 350000 action not neighbor significando que o receptor descartou a correcao por ja ter 3 sensores mais proximos 78 Desconexao de um Sensor Se o cliente em 44 fechar com Ctrl C o servidor detecta e envia uma mensagem com measurement 10000 23 log temperature sensor in 44 measurement 10000 Todos os clientes do tipo temperature recebem isso e exibem log temperature sensor in 44 measurement 10000 action removed indicando que aquele sensor saiu do sistema 8 Conclusao Este projeto ilustra o uso de programacao em rede sockets POSIX bem como threads para lidar com multiplas conexoes simultˆaneas Tambem demonstra um minisistema de publishsubscribe baseado em tipos de sen sores aliando conceitos de redes de computadores e de Redes de Sensores Sem Fio RSSF Logs padronizados no servidor para cada medicao recebida Logs nos clientes indicando same location not neighbor correction of ou removed Atualizacao das leituras periodicamente sempre respeitando o limite maximo e mınimo do tipo de sensor 24