Introdução às Redes em Java
Visão geral das APIs de rede Java em java.net e java.net.http para conectar-se a serviços remotos.
Redes é a forma como um programa Java se comunica com outro — seja na mesma sala ou do outro lado do mundo. O JDK inclui uma pilha completa para isso em dois pacotes: o antigo java.net (URLs, sockets, endereços) e o moderno java.net.http (HttpClient introduzido no Java 11). Esta parte do livro percorre essa pilha desde as conveniências de alto nível até os sockets brutos.
As camadas, do alto ao baixo
As APIs de rede do Java formam uma escada. Escolha o degrau mais alto que resolva o problema:
| Degrau | API | Use para |
|---|---|---|
| Mais alto | HttpClient (java.net.http) | HTTP/HTTPS moderno: chamadas REST, downloads, assíncrono |
URL / URLConnection / HttpURLConnection | HTTP legado e outros protocolos URL | |
Socket / ServerSocket | Protocolos TCP personalizados, seu próprio cliente/servidor | |
| Mais baixo | DatagramSocket | Mensagens UDP sem conexão |
| Suporte | InetAddress | Resolução e representação de endereços IP |
A regra geral: se você está chamando uma API HTTP, use HttpClient. Desça para sockets apenas quando estiver usando um protocolo não-HTTP ou construindo um servidor próprio.
TCP vs. UDP
Dois protocolos de transporte estão na base de quase tudo:
- TCP (
Socket,ServerSocket) é uma conexão: confiável, ordenada, baseada em fluxo. Os bytes que você escreve chegam intactos e em ordem, ou você recebe um erro. HTTP, bancos de dados e a maioria dos protocolos de aplicação operam sobre TCP. - UDP (
DatagramSocket) é sem conexão: você dispara pacotes independentes ("datagramas") sem handshake, sem ordenação e sem garantia de entrega. Ele troca confiabilidade por baixa latência — usado para DNS, streaming de vídeo e jogos.
Cliente vs. servidor
Um cliente inicia uma conexão com um endereço e porta conhecidos. Um servidor se vincula a uma porta e aguarda para aceitar conexões de entrada. A mesma classe Socket representa a conexão ativa em ambos os lados; a assimetria está apenas em quem inicia a conversa. Capítulos posteriores constroem os dois lados.
Bloqueante por padrão
As APIs clássicas do java.net são bloqueantes: socket.getInputStream().read() suspende a thread chamadora até que os dados cheguem, e serverSocket.accept() suspende até que um cliente se conecte. Isso é simples de entender, mas significa uma thread por conexão. (Canais java.nio e threads virtuais resolvem a escalabilidade; esta parte usa as APIs bloqueantes, que são o ponto de partida correto.)
Um exemplo completo: toda a pilha em um único arquivo
Para tornar as peças concretas, este programa inicia um pequeno servidor HTTP na interface de loopback e então o chama com o HttpClient moderno — uma viagem completa de ida e volta cliente/servidor em uma única JVM, sem rede externa necessária.
O que observar na execução:
- Um cliente e servidor funcionais cabem em um arquivo curto. Aplicações reais os separam entre máquinas, mas a API é idêntica —
HttpServeraceitou uma conexão eHttpClientabriu uma, encontrando-se via TCP na interface de loopback (127.0.0.1). Esta é a forma de todo programa em rede: um lado espera, o outro chama. - Vincular à porta 0 permite que o SO escolha uma porta livre, que
server.getAddress().getPort()retorna. Fixar uma porta arrisca "endereço já em uso"; porta 0 é o truque padrão para testes e demonstrações que precisam apenas de uma porta. - O cliente nunca tocou em um socket diretamente.
HttpClientcuidou da conexão, da linha de requisição HTTP, dos cabeçalhos e da análise da resposta — esse é o valor de subir ao degrau mais alto da escada. Os capítulos sobre sockets mostrarão o que foi escondido. - A resposta carregava metadados estruturados: um
statusCode()(200), umbody()e umaversion(). Respostas HTTP são mais do que texto; o cliente as modelou como um objeto tipadoHttpResponse, então você lê campos em vez de analisar um fluxo. server.stop(0)liberou a porta. Recursos de rede — sockets, portas de servidor, conexões — são handles escassos do SO; cada capítulo desta parte os fecha explicitamente (ou com try-with-resources) para que não haja vazamentos.
O que o restante desta parte cobre
Os capítulos a seguir percorrem a escada de cima para baixo:
- A classe
URLeURLConnection/HttpURLConnection— análise de URLs e a API de conexão legada. - O
HttpClientmoderno em profundidade — requisições HTTP/2 síncronas e assíncronas. - TCP bruto com
SocketeServerSocket— construindo seu próprio cliente e servidor. - UDP sem conexão com
DatagramSocket. - Resolução de endereços com
InetAddress.
O próximo capítulo começa com o objeto de rede mais familiar de todos: a URL.