Introducción a las Redes en Java
Resumen de las APIs de red de Java en java.net y java.net.http para conectarse a servicios remotos.
Las redes son la manera en que un programa Java se comunica con otro programa — en la misma sala o al otro lado del mundo. El JDK incluye una pila completa y lista para usar en dos paquetes: el clásico java.net (URLs, sockets, direcciones) y el moderno java.net.http (el HttpClient introducido en Java 11). Esta parte del libro recorre esa pila desde las conveniencias de alto nivel hasta los sockets sin procesar.
Las capas, de mayor a menor nivel
Las APIs de red de Java forman una escalera. Elige el peldaño más alto que cumpla el propósito:
| Peldaño | API | Úsala para |
|---|---|---|
| El más alto | HttpClient (java.net.http) | HTTP/HTTPS moderno: llamadas REST, descargas, asíncrono |
URL / URLConnection / HttpURLConnection | HTTP heredado y otros protocolos URL | |
Socket / ServerSocket | Protocolos TCP personalizados, tu propio cliente/servidor | |
| El más bajo | DatagramSocket | Mensajería UDP sin conexión |
| Soporte | InetAddress | Resolver y representar direcciones IP |
La regla general: si estás llamando a una API HTTP, usa HttpClient. Baja a los sockets solo cuando estés hablando un protocolo que no sea HTTP o cuando construyas tu propio servidor.
TCP vs. UDP
Dos protocolos de transporte subyacen a casi todo:
- TCP (
Socket,ServerSocket) es una conexión: confiable, ordenada y basada en flujos. Los bytes que escribes llegan intactos y en orden, o recibes un error. HTTP, bases de datos y la mayoría de los protocolos de aplicación se apoyan en TCP. - UDP (
DatagramSocket) es sin conexión: envías paquetes independientes ("datagramas") sin apretón de manos, sin orden y sin garantía de entrega. Sacrifica la fiabilidad por baja latencia — se usa para DNS, transmisión de video y videojuegos.
Cliente vs. servidor
Un cliente inicia una conexión hacia una dirección y puerto conocidos. Un servidor se enlaza a un puerto y espera para aceptar conexiones entrantes. La misma clase Socket representa la conexión activa en ambos extremos; la asimetría solo está en quién inicia la conversación. Capítulos posteriores construyen ambos lados.
Bloqueo por defecto
Las APIs clásicas de java.net son bloqueantes: socket.getInputStream().read() suspende el hilo que lo llama hasta que llegan datos, y serverSocket.accept() suspende hasta que un cliente se conecta. Eso es simple de razonar, pero implica un hilo por conexión. (Los canales de java.nio y los hilos virtuales abordan la escalabilidad; esta parte se queda con las APIs bloqueantes, que son el punto de partida correcto.)
Un ejemplo práctico: toda la pila en un solo archivo
Para que las piezas sean concretas, este programa inicia un pequeño servidor HTTP en la interfaz de loopback y luego lo llama con el HttpClient moderno — un ciclo completo cliente/servidor en una sola JVM, sin necesidad de red externa.
Lo que se puede extraer de la ejecución:
- Un cliente y un servidor funcionales caben en un archivo corto. Las aplicaciones reales los separan en máquinas distintas, pero la API es idéntica —
HttpServeraceptó una conexión yHttpClientabrió una, encontrándose por TCP en la interfaz de loopback (127.0.0.1). Esta es la forma de todo programa en red: un lado espera, el otro llama. - Enlazarse al puerto 0 dejó que el sistema operativo eligiera un puerto libre, que
server.getAddress().getPort()notificó de vuelta. Codificar un puerto de forma fija arriesga el error "address already in use"; el puerto 0 es el truco estándar para pruebas y demos que simplemente necesitan algún puerto. - El cliente nunca tocó un socket directamente.
HttpClientgestionó la conexión, la línea de solicitud HTTP, los encabezados y el análisis de la respuesta — ese es el valor de subir al peldaño más alto de la escalera. Los capítulos sobre sockets mostrarán más adelante lo que ocultó. - La respuesta contenía metadatos estructurados: un
statusCode()(200), unbody()y unaversion(). Las respuestas HTTP son más que texto; el cliente las modeló como un objeto tipadoHttpResponsepara que puedas leer campos en lugar de analizar un flujo. server.stop(0)liberó el puerto. Los recursos de red — sockets, puertos de servidor, conexiones — son manejadores escasos del sistema operativo; cada capítulo de esta parte los cierra explícitamente (o con try-with-resources) para que no haya fugas.
Qué cubre el resto de esta parte
Los capítulos siguientes recorren la escalera hacia abajo:
- La clase
URLyURLConnection/HttpURLConnection— análisis de URLs y la API de conexión heredada. - El
HttpClientmoderno en profundidad — solicitudes HTTP/2 síncronas y asíncronas. - TCP sin procesar con
SocketyServerSocket— construyendo tu propio cliente y servidor. - UDP sin conexión con
DatagramSocket. - Resolución de direcciones con
InetAddress.
El siguiente capítulo comienza con el objeto de red más familiar de todos: la URL.