Paseando por la Red

Es muy sencillo acceder a archivos en la red utilizando Java.El paquete java.net dispone de varias clases e interfases a talefecto.

En primer lugar, la clase URL nos permite definir un recurso enla red de varias maneras, por ejemplo:

URL url1 = new URL ("http://www.rockar.com.ar/index.html");URL url2 = new URL ("http", "www.rockar.com.ar", "sbits.htm");

Por otra parte, podemos establecer una conexión a un URLdado mediante openConnection:

URLConnection conexion = url.openConnection();

Una vez lograda la conexión, podemos leer y escribir datosutilizando streams (corrientes de datos), comoen el caso de manejo de archivos comunes (ver capítuloX). Un DataInputStream nos permite leerdatos que llegan a través de la red, y un DataOutputStreamnos permite enviar datos al host.

Por ejemplo:

DataInputStream datos = new DataInputStream( corrienteEntrada  );

En nuestro caso, la corriente de entrada de datos proviene dela conexión al URL. El método getInputStream()del objeto URLConnection nos proveetal corriente:

DataInputStream datos = new DataInputStream(conex.getInputStream())

De este modo podemos escribir un pequeño programa para,por ejemplo, leer una página HTML desde una direcciónarbitraria de internet. El programa, luego de compilarse mediantejavac Ejemplo25.java, se ejecuta con java Ejemplo25<url>; por ejemplo: java Ejemplo25http://www.rockar.com.ar/index.html.

import java.io.*;import java.net.*;public class Ejemplo25 {	public static void main(String argv[]) {	   String s;	   try {		URL url = new URL (argv[0]);		URLConnection conex = url.openConnection();		System.out.println("Cargando "+argv[0]);		DataInputStream datos = new DataInputStream(conex.getInputStream());		do {			s = datos.readLine();			if (s != null) System.out.println(s);		} while (s != null);	   }	   catch (ArrayIndexOutOfBoundsException e) {		System.out.println("Sintaxis: java Ejemplo25 <url>");	   }	   catch (UnknownHostException e) {		System.out.println("El host no existe o no responde");	   }	   catch (Exception e) {		e.printStackTrace();	   }	}}

Este programa muestra el HTML como texto en la pantalla, peropodríamos grabarlo a un archivo para guardarlo. Inclusive,podríamos procesarlo a medida que lo recibimos, identificarlos tags <A HREF=url>, guardarlos en un vector, y seguidamenteconectarnos y bajar los links que figuran en la páginaoriginal hasta bajar un site completo.

Noten que esto no sólo sirve para establecer conexionesa páginas HTML. En realidad, un URL puede referirse tambiéna otros protocolos, como gopher, ftp, etcétera; si biensegún la implementación de Java puede haber problemaspara conectarse a algunos tipos de URL.

Para ver los tipos de URL posibles les recomiendo leer la página:

http://www.ncsa.uiuc.edu/demoweb/url-primer.html

Los Sockets

Los sockets (zócalos, referido a los enchufes deconexión de cables) son mecanismos de comunicaciónentre programas a través de una red TCP/IP. De hecho, alestablecer una conexión via Internet estamos utilizandosockets: los sockets realizan la interfase entre la aplicacióny el protocolo TCP/IP.

Dichos mecanismos pueden tener lugar dentro de la misma máquinao a través de una red. Se usan en forma cliente-servidor:cuando un cliente y un servidor establecen una conexión,lo hacen a través de un socket. Java proporciona para estolas clases ServerSocket y Socket.

Los sockets tienen asociado un port (puerto). En general,las conexiones via internet pueden establecer un puerto particular(por ejemplo, en http://www.rockar.com.ar:80/index.htmlel puerto es el 80). Esto casi nunca se especifica porque ya haydefinidos puertos por defecto para distintos protocolos: 20 paraftp-data, 21 para ftp, 79 para finger, etc. Algunos servers puedendefinir otros puertos, e inclusive pueden utilizarse puertos disponiblespara establecer conexiones especiales.

Justamente, una de las formas de crear un objeto de la clase URLpermite especificar también el puerto:

URL url3 = new URL ("http", "www.rockar.com.ar", 80,"sbits.htm");

Para establecer una conexión a través de un socket,tenemos que programar por un lado el servidor y por otro los clientes.

En el servidor, creamos un objeto de la clase ServerSockety luego esperamos algún cliente (de clase Socket)mediante el método accept():

ServerSocket conexion = new ServerSocket(5000);	// 5000 es el puerto en este casoSocket cliente = conexion.accept();			// espero al cliente

Desde el punto de vista del cliente, necesitamos un Socket alque le indiquemos la dirección del servidor y el númerode puerto a usar:

Socket conexion = new Socket ( direccion, 5000 );

Una vez establecida la conexión, podemos intercambiar datosusando streams como en el ejemplo anterior. Como la clase URLConnection,la clase Socket dispone de métodosgetInputStream y getOutputStreamque nos dan respectivamente un InputStreamy un OutputStream a través delos cuales transferir los datos.

Un servidor atento

Vamos a crear un servidor Ejemplo26a.java(que podemos correr en una ventana) que atenderá a un clientede la misma máquina (lo vamos a correr en otra ventana).Para hacerlo simple, el servidor sólo le enviaráun mensaje al cliente y éste terminará la conexión.El servidor quedará entonces disponible para otro cliente.

Es importante notar que, para que el socket funcione, los serviciosTCP/IP deben estar activos (aunque ambos programas corran en lamisma máquina). Los usuarios de Windows asegúrenseque haya una conexión TCP/IP activa, ya sea a una red localo a Internet.

El servidor correrá "para siempre", asíque para detenerlo presionen control-C.

// servidorimport java.io.*;import java.net.*;public class Ejemplo26a {	public static void main(String argv[]) {	  ServerSocket	servidor;	  Socket	cliente;	  int		numCliente = 0;	  try {		servidor = new ServerSocket(5000);		do {		  numCliente++;		  cliente = servidor.accept();		  System.out.println("Llega el cliente "+numCliente);		  PrintStream ps = new PrintStream(cliente.getOutputStream());		  ps.println("Usted es mi cliente "+numCliente);		  cliente.close();		} while (true);	  }		  catch (Exception e) {		e.printStackTrace();	  }	}}

Utilizamos un PrintStream para enviarlos datos al cliente, ya que es sencillo de utilizar para mandarStrings. El método PrintStream.printlnmaneja los datos como System.out.println,simplemente hay que indicarle el stream a través del cualmandarlos al crearlo (en este caso, el OutputStreamdel cliente, que obtenemos con cliente.getOutputStream()).

El cliente satisfecho

Ahora vamos a crear la clase cliente, Ejemplo26b.java.El cliente simplemente establece la conexión, lee a travésde un DataInputStream (mediante el métodoreadLine()) lo que el servidor le manda,lo muestra y corta.

// cliente:import java.io.*;import java.net.*;public class Ejemplo26b {	public static void main(String argv[]) {	  InetAddress	direccion;	  Socket	servidor;	  int		numCliente = 0;	  try {		direccion = InetAddress.getLocalHost();	 // direccion local		servidor = new Socket(direccion, 5000);		DataInputStream datos =			new DataInputStream(servidor.getInputStream());		System.out.println( datos.readLine() );		servidor.close();	  }		  catch (Exception e) {		e.printStackTrace();	  }	}}

Para probar esto, asegúrense que los servicios TCP/IP esténactivos, corran java Ejemplo26a en unaventana y corran varias veces java Ejemplo26ben otra. Las salidas serán más o menos así:

Ventana servidor:

C:\java\curso>java Ejemplo26aLlega el cliente 1Llega el cliente 2Llega el cliente 3	(----- cortar con control-C -----)

Ventana cliente:

C:\java\curso>java Ejemplo26bUsted es mi cliente 1C:\java\curso>java Ejemplo26bUsted es mi cliente 2C:\java\curso>java Ejemplo26bUsted es mi cliente 3	(----- aquí cerramos el servidor -----)C:\java\curso>java Ejemplo26bjava.net.SocketException: connect        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:223)        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:128)        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:115)        at java.net.Socket.<init>(Socket.java:125)        at java.net.Socket.<init>(Socket.java:101)        at Ejemplo26b.main(Ejemplo26b.java:12)

Esto es todo por ahora. El ejemplo fue lo más sencilloposible, pero mediante el mismo método el servidor y losclientes pueden intercambiar datos escribiendo en ambas direcciones.Inclusive, el servidor puede correr en una máquina y losclientes en otras; además, si bien en este caso utilizamosaplicaciones standalone, se pueden utilizar applets.

Por ejemplo, una aplicación servidora puede correr constantementeen un server de Internet (por ejemplo, para buscar datos en unabase de datos) y diferentes clientes en distintas máquinas,posioblemente applets Java, pueden conectarse a ella y consultarla.


 

<> Página de tutoriales <> Página Anterior <>