Este projeto implementa uma aplicação cliente-servidor de eco (Echo) sobre o protocolo TCP, utilizando um servidor multithreaded para gerenciar conexões simultâneas e um cliente interativo para testar a comunicação, medindo também a latência das requisições.
- 
Servidor TCP Multithreaded: aceita e gerencia conexões de múltiplos clientes simultaneamente, utilizando threads para processar as conexões de forma independente e eficiente. Ele usa uma fila para gerenciar as requisições de maneira organizada, de modo a atender um cliente por vez. 
- 
Cliente TCP: permite que o usuário digite mensagens no console ( stdin) e receba a resposta de eco do servidor.
- 
Medição de Latência: o cliente calcula e exibe a latência de ponta a ponta de cada requisição. 
- 
Gerenciamento de Argumentos: a classe FlagParserorganiza e valida os parâmetros passados pela linha de comando.
- 
Tratamento de Erros: O servidor implementa um sistema de timeoutpara encerrar conexões inativas.
O projeto é composto pelas seguintes classes e interfaces principais:
- 
Main.java: lida com a lógica de inicialização do servidor ou cliente com base nos argumentos de linha de comando.
- 
TcpEchoServer.javaeTcpEchoServerImpl.java: interface e sua implementação do servidor. Aceita conexões em uma porta específica e ecoa as mensagens recebidas.
- 
TcpEchoClient.javaeTcpEchoClientImpl.java: interface e sua implementação do cliente. Conecta-se a um servidor, envia mensagens e mede a latência da resposta.
- 
FlagParser.java: classe utilitária responsável por analisar os argumentos de linha de comando, como--server,--client,--ipe--port.
- 
ConnectionException.java: exceção personalizada que encapsula erros de conexão, tornando o tratamento de erros mais claro.
Para executar o projeto, você precisa ter o Java Development Kit (JDK) 8 ou superior e o Apache Maven instalados.
Abra o terminal e, a partir da pasta raiz do projeto (echo/), execute o seguinte comando Maven para compilar o código e criar um arquivo JAR executável:
    mvn clean package
Este comando irá compilar todas as classes e empacotar a aplicação em um arquivo .jar na pasta target/.
A execução deve ser feita a partir da pasta raiz do seu projeto (echo/). Utilize os seguintes comandos, dependendo do modo desejado:
Modo servidor:
  mvn exec:java -Dexec.mainClass="com.br.Main" -Dexec.args="--server --port=<PORTA>"
Modo cliente:
  mvn exec:java -Dexec.mainClass="com.br.Main" -Dexec.args="--client --ip=<IP> --port=<PORTA>"
Observação: Substitua
<IP>e<PORTA>pelos valores desejados.
Inicie o servidor em uma porta de sua escolha (ex: porta 8080):
  (Terminal 1)
  mvn exec:java -Dexec.mainClass="com.br.Main" -Dexec.args="--server --port=8080"   
Saída esperada:
  Servidor conectado na porta: 8080
Em uma nova janela do terminal, inicie o cliente. Conecte-se ao servidor na mesma porta (8080) e no IP local (127.0.0.1 --> localhost):
  (Terminal 2)
  mvn exec:java -Dexec.mainClass="com.br.Main" -Dexec.args="--client --ip=localhost --port=8080"
Saída esperada:
  Conectado ao host: localhost:8080
  Servidor: Sua conexão foi enfileirada. Aguarde para ser atendido.
  Servidor: O servidor está pronto para processar sua conexão.
Agora você pode digitar qualquer mensagem no terminal do cliente. A mensagem será enviada ao servidor, que a ecoará de volta. A latência será exibida após cada resposta.
  Terminal 2 (cliente)
  Hello, world!
  Servidor: Hello, world!
  Latência: 0.123 ms
  Como vai?
  Servidor: Como vai?
  Latência: 0.234 ms
  quit
  Fechando conexão.
No terminal do servidor, você verá o registro das mensagens e das conexões:
  Terminal 1 (servidor)
  Nova conexão aceita: /127.0.0.1:54321
  Atendendo cliente: /127.0.0.1:54321
  Mensagem recebida: Hello, world!
  Mensagem recebida: Como vai?
  Conexão finalizada pelo cliente.
O comando quit encerra a conexão do cliente de forma limpa.
- 
Linguagem: Java 
- 
Gerenciamento de Dependências: Apache Maven 
- 
Comunicação: TCP Sockets 
- 
Paralelismo: BlockingQueue e Threads