|
| Volver a índice |
Este capítulo cubre el paquete java.net. La integración de Java con la red se ha hecho legendaria, gracias en gran parte a esta biblioteca de clases. Java admite el protocolo de TCP/IP de Internet ampliando la interfaz de E/S de flujo ya establecida, presentada en el capítulo anterior, y aņadiendo las características que se necesitan para crear objetos de E/S a través de la red. Java admite las familias de protocolo TCP y UDP. TCP se utiliza para E/S fiable de tipo secuencial a través de la red. UDP admite un modelo más rápido, punto a punto y orientado a datagrama.
Independientemente de si se realiza una llamada telefónica, se envía un correo electrónico o se establece una conexión a través de Internet, las direcciones son fundamentales. Java admite los nombres de Internet a través de la clase InetAddress. Las direcciones de Internet, reducidas a su nivel más bajo, están formadas por un identificador de nodo de 32 bits y un selector de puerto de ese nodo de 32 bits. En Internet el direccionamiento lo gestionan servidores de nombres que traducen nombres habituales y fáciles de recordar a sus correspondientes direcciones de 32 bits.
La clase InetAddress no tiene constructores visibles. Para crear un objeto InetAddress, se tiene que utilizar uno de los métodos de fábrica disponibles. Estos métodos son simplemente métodos estáticos que devuelven una instancia de la clase en la que residen. En este caso, InetAddress tiene tres métodos, getLocalHost, getByName y getAllByName, que se pueden utilizar para crear instancias de InetAddress.
La clase InetAddress también tiene unos cuantos métodos no estáticos, que se pueden utilizar sobre los objetos devueltos por los métodos que se acaban de mencionar:
Los datagramas son bloques de información del tipo "lanzar y olvidar" que se transfieren a través de la red. Para la mayoría de los programas de la red, el utilizar un flujo TCP/IP en vez de un datagrama UPD es más sencillo y hay menos posibilidades de tener problemas. Sin embargo, cuando se requiere un rendimiento óptimo, y está justificado el tiempo adicional que supone el realizar la verificación de los datos, los datagramas son un mecanismo realmente útil.
Cuando se ha lanzado un datagrama hacia su destino, no hay ninguna seguridad de que llegue o incluso de que haya alguien allí para cogerlo. Igualmente, cuando se recibe un datagrama, no es seguro que no se haya daņado por el camino o que el que lo haya enviado esté todavía ahí para recibir una respuesta.
Se pueden crear los DatagramPackets utilizando dos constructores. El primero utiliza solamente un buffer de bytes y una longitud. Ese utiliza para recibir datos a través de un DatagramSocket. El segundo aņade una especificación de dirección de destino y un puerto, que es utilizada por un DatagramSocket para determinar dónde se enviarán los datos del paquete. Considerar que estas dos formas equivalen a crear un "un buzón de entrada" en el primer caso, y a rellenar y poner una dirección en un sobre en el segundo. Estos son los prototipos de los dos constructores:
DatagramPacket(byte ibuf[], int ilong);
DatagramPacket(byte ibuf[], int ilong, InetAddress idir,
int ipuerto);
Hay varios métodos de acceder al estado interno de un DatagramPacket. Permiten un acceso completo a la dirección de destino y número de puerto de un paquete, además de a sus datos y su longitud. A continuación se presenta un resumen de cada uno de ellos:
Los conectores (sockets), o los conectores TCP/IP en concreto, se utilizan para implementar conexiones basadas en flujo, punto a punto, bidireccionales y fiables entre nodos de Internet. Se puede utilizar un conector para conectar el sistema de E/S de Java a otros programas que pueden residir en la máquina local o en cualquier otra máquina de Internet. La clase Socket, a diferencia de DatagramSocket, implementa una conexión continua muy fiable entre el cliente y el servidor.
Al crear un objeto conector también se establece la conexión entre direcciones de Internet. No hay métodos ni constructores que muestren explícitamente los detalles del establecimiento de la conexión del cliente. Se puedan utilizar dos constructores para crear conectores:
En un conector se puede examinar en cualquier momento la información de dirección y puerto asociada con él utilizando los métodos siguientes:
Cuando se ha creado el objeto Socket, también puede ser examinado para acceder a los flujos de entrada y salida asociados con él. Todos estos métodos pueden lanzar una IOException si se han invalidado los conectores debido a una pérdida de conexión en la red. Estos flujos se utilizan exactamente igual que los flujos de E/S que hemos visto en el capítulo anterior para enviar y recibir datos:
Los ServerSockets se deben utilizar para crear servidores de Internet. Estos servidores no son necesariamente máquinas, de hecho son programas que están esperando a que programas cliente locales o remotos se conecten a ellos en puertos públicos. Los ServerSockets son bastante diferentes de los Sockets normales. Cuando se crea un ServerSocket, se registrará en el sistema que tiene interés en conexiones de cliente. Tiene un método adicional, accept, que es una llamada que se bloquea ya que espera que un cliente inicie la comunicación y después devuelve un Socket normal.
Los dos constructores de ServerSocket reflejan el número del puerto en el que se desean aceptar las conexiones y, opcionalmente, durante cuánto tiempo se desea esperar a que se deje de utilizar el puerto. Ambos constructores pueden lanzar una IOExeption bajo condiciones adversas. Estos son los dos prototipos:
Funcionalmente, el método accept de un ServerSocket es una llamada que se bloquea y que espera que un cliente inicie la comunicación y después devuelve un Socket normal. Después, este conector se utiliza para la comunicación con el cliente.
Un URL proporciona una forma razonablemente inteligente de identificar o direccionar de manera única la información en Internet. Los localizadores de recursos uniformes(URL) son los componentes más importantes de la red mundial. Tienen el don de la ubicuidad; todo visualizador utiliza URL para identificar la información de la red. De hecho, la red se reduce a Internet con todos los recursos direccionados como URL, con HTML, funcionando como lenguaje para la visualización de la información contenida en los URL y que proporciona una interfaz del tipo "apuntar y pulsar" para ir a otros URL. Dentro de la biblioteca de clases de red, la clase URL proporciona una API simple y concisa para acceder a la información a través de Internet utilizando URL.
La clase URL de Java tiene cuatro constructores, y todos ellos pueden lanzar una MalformedURLException. La forma más utilizada habitualmente especifica el URL con una String que es idéntica a lo que se muestra en un visualizador.
URL(String espec);
Las dos formas siguientes del constructor permiten que se descomponga el URL en las partes que lo componen:
URL(String protocolo, String nodo, int puerto, String archivo);
URL(String protocolo, String nodo, String archivo);
El cuarto constructor permite utilizar un URL como contexto de referencia y después crea un nuevo URL desde ese contexto. Aunque esto parece un poco retorcido, realmente es bastante sencillo y útil:
URL(URL1 contexto, String espec);
Una URLConnection es el objeto que utilizamos para examinar las propiedades del recurso remoto referenciado o para obtener su contenido. En la práctica, hay un poco de solapamiento entre estas funciones. Por ejemplo, podemos establecer condiciones de estado dentro de la URLConnection de manera que sólo se devuelva el contenido del URL si se cumplan unas ciertas condiciones. Estas condiciones se corresponden y son sólo útiles en relación a la especificación de protocolo HTTP.