W3docs

Introducción a la programación de redes en Java

Una visión general de las API de red de Java en java.net y java.net.http para conectarse a servicios remotos.

Introducción a la programación de redes en Java

La programación de redes es cómo un programa Java habla con otro programa — al otro lado de la sala o al otro lado del mundo. El JDK incluye para ello una pila completa, con todo incorporado, en dos paquetes: el veterano 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 comodidades de alto nivel hasta los sockets en bruto.

Las capas, de alta a baja

Las API de red de Java forman una escalera. Elija el peldaño más alto que haga el trabajo:

PeldañoAPIÚsela para
El más altoHttpClient (java.net.http)HTTP/HTTPS moderno: llamadas REST, descargas, asíncrono
URL / URLConnection / HttpURLConnectionHTTP heredado y otros protocolos de URL
Socket / ServerSocketProtocolos TCP personalizados, su propio cliente/servidor
El más bajoDatagramSocketMensajería UDP sin conexión
ApoyoInetAddressResolución y representación de direcciones IP

La regla general: si está llamando a una API HTTP, recurra a HttpClient. Baje a los sockets solo cuando hable un protocolo distinto de HTTP o construya un servidor propio.

TCP vs. UDP

Dos protocolos de transporte subyacen a casi todo:

  • TCP (Socket, ServerSocket) es una conexión: fiable, ordenada, basada en flujo. Los bytes que escribe llegan intactos y en orden, o recibe un error. HTTP, las bases de datos y la mayoría de los protocolos de aplicación viajan sobre TCP.
  • UDP (DatagramSocket) es sin conexión: usted dispara paquetes independientes («datagramas») sin apretón de manos, sin orden y sin garantía de entrega. Cambia la fiabilidad por baja latencia — usado para DNS, transmisión de vídeo y juegos.

Cliente vs. servidor

Un cliente inicia una conexión hacia una dirección y un 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 está solo en quién inicia la conversación. Los capítulos posteriores construyen ambos lados.

Bloqueantes por defecto

Las API clásicas de java.net son bloqueantes: socket.getInputStream().read() aparca el hilo que llama hasta que llegan datos, y serverSocket.accept() aparca hasta que un cliente se conecta. Es sencillo de razonar pero significa un hilo por conexión. (Los canales de java.nio y los hilos virtuales abordan la escalabilidad; esta parte se queda en las API bloqueantes, que son el punto de partida correcto.)

Un ejemplo trabajado: toda la pila en un solo archivo

Para hacer las piezas concretas, este programa arranca un servidor HTTP diminuto en la interfaz de bucle invertido, y luego lo llama con el moderno HttpClient — un viaje de ida y vuelta cliente/servidor completo en una sola JVM, sin necesidad de una red externa.

java— editable, runs on the server

Qué llevarse de la ejecución:

  • Un cliente y un servidor funcionales caben en un archivo corto. Las aplicaciones reales los reparten entre máquinas, pero la API es idéntica — HttpServer aceptó una conexión y HttpClient abrió una, encontrándose sobre TCP en la interfaz de bucle invertido (127.0.0.1). Esta es la forma de todo programa en red: un lado espera, un lado llama.
  • Enlazar al puerto 0 dejó que el sistema operativo eligiera un puerto libre, que server.getAddress().getPort() informó de vuelta. Codificar un puerto a mano arriesga «address already in use»; el puerto 0 es el truco estándar para pruebas y demos que solo necesitan un puerto.
  • El cliente nunca tocó un socket directamente. HttpClient manejó la conexión, la línea de solicitud HTTP, las cabeceras 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 de sockets, más adelante, muestran lo que ocultó.
  • La respuesta llevaba metadatos estructurados: un statusCode() (200), un body() y una version(). Las respuestas HTTP son más que texto; el cliente las modeló como un objeto HttpResponse tipado, de modo que usted lee campos en lugar de analizar un flujo.
  • server.stop(0) liberó el puerto. Los recursos de red — sockets, puertos de servidor, conexiones — son escasos handles del sistema operativo; cada capítulo de esta parte los cierra explícitamente (o con try-with-resources) para que no se filtren.

Qué cubre el resto de esta parte

URL y sus clases de conexión, el moderno HttpClient en profundidad, TCP en bruto con Socket y ServerSocket, UDP sin conexión con DatagramSocket, y la resolución de direcciones con InetAddress. El siguiente capítulo empieza por el objeto de red más familiar de todos: la URL.

Práctica

Práctica

Está escribiendo un servicio Java que llama a una API REST de terceros sobre HTTPS y necesita solicitudes tanto síncronas como asíncronas en un JDK moderno. ¿Qué API es la primera opción más apropiada?