- Letícia Mariana da Silva Ferreira
- Paulo Sérgio Amorim Mônico
O trabalho visa implementar uma arquitetura cliente-servidor para streaming de áudio por meio do protocolo TCP em C. A arquitetura é baseada em apenas uma conexão tcp entre cliente e servidor (destinada a comandos e a streaming de áudio), event-driven programming utilizando epoll, multithreading utilizando a biblioteca pthread.
Execute este comando para clonar o repositório:
git clone https://github.com/paulosergioamorim/networking_audio_streaming.gitExecute este comando:
makeEsse comando gerará dois programas: client e server.
Primeiro, execute este comando para iniciar o servidor:
./server -ipaddr <ipaddr> -port <port>Para pedir ajuda, execute este comando:
./server -helpEm seguida, execute este comando para iniciar o cliente:
./client -ipaddr <server-ipaddr> -port <server-port>Para pedir ajuda, execute este comando:
./client -helpExecute o comando /help para listar todos os comandos possíveis.
libvlc: para reprodução de áudio no cliente.libvlc-devem distros Debian based.std_ds.h: single-header library para hash tables em C.logger.h: biblioteca para logging.
- Multiplexação de IO no servidor: isso permitiu um baixo de consumo de recursos
por conexão no servidor. Não é criado um novo processo nem uma nova thread. Os sockets
são consumidos sobre demanda utilizando
epoll, API específica do Linux. - Único socket TCP entre cliente e servidor: permitiu que o file descriptor do socket
de conexão do cliente fosse uma chave num hashmap de estados do cliente. Mapeamento mais simples.
Houve alguns problemas com uma implementação de duplo aceite (dois
accept()) como geração de uma chave única e "linkagem" entre os dois sockets. - Multiplexação de IO no cliente: utilização de apenas uma única thread. Utilização do
epollpara consumir a entrada padrão e o socket TCP no loop. Evitou possíveis dificuldades com condições de corrida e integração com a bibliotecalibvlc. - Mensagens de tamanho variável: o cliente e servidor se comunicam entre si com mensagens de tamanho
enxuto, graças ao header da requisição e resposta. Somente mensagens que realmente necessitam do campo
bufo enviam.
- Criação de um protocolo de aplicação em cima do TCP para streaming de áudio
- Criação de uma fila bloqueante
- Envio e resposta de comandos
- Envio e streaming de áudio no cliente
- Gerenciamento de conexões por meio de multiplexação de IO
- Análise de métricas no cliente utilizando one-way delay
- Amostra obtida numa VPN com tráfego zero.
pcap/command_list.pcapng: cliente se conecta, executa o/liste/exit.pcap/command_start.pcapng: cliente se conecta, executa o/start,/stop,/resumee/exit.
- Melhorar multiplexação de IO e sockets não bloqueantes
- Uso de Edge-Triggered no
epolle uso total de sockets não bloqueantes. - Atualização:: uso de
mmap()para mapeamento de arquivos de áudio esendmsg()para envio de mensgagens comoKIND_LISTeKIND_STREAM
- Melhorar a implementação com TCP
- Criação de dois canais tcp separados: um para comandos e outro para áudio. Pensar numa melhor estratégia de "linkar" os dois sockets indicando que são de um mesmo cliente. Atualização: não.
- Melhor tratamento ao ocorrer TCP Zero Window. Atualização: usando um timer para envio de stream.
- Utilizar outros protocolos
- Usar UDP no streaming de áudio. Algumas dificuldades como entrega em ordem, confiável e controle de congestionamento. Atulização: talvez
- Usar QUIC no streaming de áudio. Reimplementar a arquitetura do zero. Atualização: será refeito futuramente em Go
- Atualização: Melhorar implementação do consumo de áudio
- Trocar implementação de fila? Permitir um futuro comando /seek?