?? java17.htm
字號:
<HTML>
<HEAD>
<TITLE>Java desde Cero</TITLE>
<META NAME="GENERATOR" CONTENT="Internet Assistant for Microsoft Word 2.0z">
</HEAD>
<BODY background=/iconos/1.gif TEXT=000000 LINK=FF0000 VLINK=A62A2A>
<H1>Paseando por la Red<BR>
</H1>
<P>
Es muy sencillo acceder a archivos en la red utilizando Java.
El paquete java.net dispone de varias clases e interfases a tal
efecto.
<P>
En primer lugar, la clase URL nos permite definir un recurso en
la red de varias maneras, por ejemplo:
<PRE>
<FONT SIZE=2>URL url1 = new URL ("http://www.rockar.com.ar/index.html");
URL url2 = new URL ("http", "www.rockar.com.ar", "sbits.htm");
<BR>
</FONT>
</PRE>
<P>
Por otra parte, podemos establecer una conexión a un URL
dado mediante <FONT FACE="Arial">openConnection</FONT>:
<PRE>
<FONT SIZE=2>URLConnection conexion = url.openConnection();<BR>
</FONT>
</PRE>
<P>
Una vez lograda la conexión, podemos leer y escribir datos
utilizando <I>streams</I> (<I>corrientes</I> de datos), como
en el caso de manejo de archivos comunes (ver capítulo
X). Un <FONT FACE="Arial">DataInputStream</FONT> nos permite leer
datos que llegan a través de la red, y un <FONT FACE="Arial">DataOutputStream</FONT>
nos permite enviar datos al host.
<P>
Por ejemplo:
<PRE>
<FONT SIZE=2>DataInputStream datos = new DataInputStream( corrienteEntrada );
<BR>
</FONT>
</PRE>
<P>
En nuestro caso, la corriente de entrada de datos proviene de
la conexión al URL. El método <FONT FACE="Arial">getInputStream()</FONT>
del objeto <FONT FACE="Arial">URLConnection</FONT> nos provee
tal corriente:
<PRE>
<FONT SIZE=2>DataInputStream datos = new DataInputStream(conex.getInputStream())
<BR>
</FONT>
</PRE>
<P>
De este modo podemos escribir un pequeño programa para,
por ejemplo, leer una página HTML desde una dirección
arbitraria de internet. El programa, luego de compilarse mediante
<I>javac Ejemplo25.java</I>, se ejecuta con <I>java Ejemplo25
<url>;</I> por ejemplo: <FONT FACE="Arial">java Ejemplo25
http://www.rockar.com.ar/index.html</FONT>.<BR>
<PRE>
<FONT SIZE=2>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();
}
}
}<BR>
</FONT>
</PRE>
<P>
Este programa muestra el HTML como texto en la pantalla, pero
podríamos grabarlo a un archivo para guardarlo. Inclusive,
podríamos procesarlo a medida que lo recibimos, identificar
los tags <A HREF=url>, guardarlos en un vector, y seguidamente
conectarnos y bajar los links que figuran en la página
original hasta bajar un site completo.
<P>
Noten que esto no sólo sirve para establecer conexiones
a páginas HTML. En realidad, un URL puede referirse también
a otros protocolos, como gopher, ftp, etcétera; si bien
según la implementación de Java puede haber problemas
para conectarse a algunos tipos de URL.
<P>
Para ver los tipos de URL posibles les recomiendo leer la página:
<PRE>
<FONT SIZE=2>http://www.ncsa.uiuc.edu/demoweb/url-primer.html
<BR>
<BR>
</FONT>
</PRE>
<H2>Los Sockets</H2>
<P>
Los <I>sockets</I> (zócalos, referido a los enchufes de
conexión de cables) son mecanismos de comunicación
entre programas a través de una red TCP/IP. De hecho, al
establecer una conexión via Internet estamos utilizando
sockets: los sockets realizan la interfase entre la aplicación
y el protocolo TCP/IP.
<P>
Dichos mecanismos pueden tener lugar dentro de la misma máquina
o 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 esto
las clases <FONT FACE="Arial">ServerSocket</FONT> y <FONT FACE="Arial">Socket</FONT>.
<P>
Los sockets tienen asociado un <I>port</I> (puerto). En general,
las conexiones via internet pueden establecer un puerto particular
(por ejemplo, en http://www.rockar.com.ar<B>:80</B>/index.html
el puerto es el 80). Esto casi nunca se especifica porque ya hay
definidos puertos por defecto para distintos protocolos: 20 para
ftp-data, 21 para ftp, 79 para finger, etc. Algunos servers pueden
definir otros puertos, e inclusive pueden utilizarse puertos disponibles
para establecer conexiones especiales.
<P>
Justamente, una de las formas de crear un objeto de la clase URL
permite especificar también el puerto:
<PRE>
<FONT SIZE=2>URL url3 = new URL ("http", "www.rockar.com.ar", 80,"sbits.htm");
<BR>
</FONT>
</PRE>
<P>
Para establecer una conexión a través de un socket,
tenemos que programar por un lado el servidor y por otro los clientes.
<P>
En el servidor, creamos un objeto de la clase <FONT FACE="Arial">ServerSocket</FONT>
y luego esperamos algún cliente (de clase <FONT FACE="Arial">Socket</FONT>)
mediante el método <FONT FACE="Arial">accept()</FONT>:
<BR>
<PRE>
<FONT SIZE=2>ServerSocket conexion = new ServerSocket(5000); // 5000 es el puerto en este caso
Socket cliente = conexion.accept(); // espero al cliente<BR>
</FONT>
</PRE>
<P>
Desde el punto de vista del cliente, necesitamos un Socket al
que le indiquemos la dirección del servidor y el número
de puerto a usar:<BR>
<PRE>
<FONT SIZE=2>Socket conexion = new Socket ( direccion, 5000 );
<BR>
</FONT>
</PRE>
<P>
Una vez establecida la conexión, podemos intercambiar datos
usando streams como en el ejemplo anterior. Como la clase <FONT FACE="Arial">URLConnection</FONT>,
la clase <FONT FACE="Arial">Socket</FONT> dispone de métodos
<FONT FACE="Arial">getInputStream</FONT> y <FONT FACE="Arial">getOutputStream</FONT>
que nos dan respectivamente un <FONT FACE="Arial">InputStream</FONT>
y un <FONT FACE="Arial">OutputStream</FONT> a través de
los cuales transferir los datos.<BR>
<H3>Un servidor atento</H3>
<P>
Vamos a crear un servidor <FONT FACE="Arial">Ejemplo26a.java</FONT>
(que podemos correr en una ventana) que atenderá a un cliente
de 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.
<P>
Es importante notar que, para que el socket funcione, los servicios
TCP/IP deben estar activos (aunque ambos programas corran en la
misma máquina). Los usuarios de Windows asegúrense
que haya una conexión TCP/IP activa, ya sea a una red local
o a Internet.
<P>
El servidor correrá "para siempre", así
que para detenerlo presionen control-C.<BR>
<PRE>
<FONT SIZE=2>// servidor
import 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();
}
}
}<BR>
</FONT>
</PRE>
<P>
Utilizamos un <FONT FACE="Arial">PrintStream</FONT> para enviar
los datos al cliente, ya que es sencillo de utilizar para mandar
<FONT FACE="Arial">String</FONT>s. El método <FONT FACE="Arial">PrintStream.println</FONT>
maneja los datos como <FONT FACE="Arial">System.out.println</FONT>,
simplemente hay que indicarle el stream a través del cual
mandarlos al crearlo (en este caso, el <FONT FACE="Arial">OutputStream</FONT>
del cliente, que obtenemos con <FONT FACE="Arial">cliente.getOutputStream()</FONT>).
<BR>
<H3>El cliente satisfecho</H3>
<P>
Ahora vamos a crear la clase cliente, <FONT FACE="Arial">Ejemplo26b.java</FONT>.
El cliente simplemente establece la conexión, lee a través
de un <FONT FACE="Arial">DataInputStream</FONT> (mediante el método
<FONT FACE="Arial">readLine()</FONT>) lo que el servidor le manda,
lo muestra y corta.<BR>
<PRE>
<FONT SIZE=2>// 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();
}
}
}<BR>
<BR>
</FONT>
</PRE>
<P>
Para probar esto, asegúrense que los servicios TCP/IP estén
activos, corran <FONT FACE="Arial">java Ejemplo26a</FONT> en una
ventana y corran varias veces <FONT FACE="Arial">java Ejemplo26b</FONT>
en otra. Las salidas serán más o menos así:
<BR>
<P>
<I><B>Ventana servidor:</B></I>
<PRE>
<FONT SIZE=2>C:\java\curso>java Ejemplo26a
Llega el cliente 1
Llega el cliente 2
Llega el cliente 3
(----- cortar con control-C -----)<BR>
</FONT>
</PRE>
<P>
<I><B>Ventana cliente:</B></I>
<PRE>
<FONT SIZE=2>C:\java\curso>java Ejemplo26b
Usted es mi cliente 1
C:\java\curso>java Ejemplo26b
Usted es mi cliente 2
C:\java\curso>java Ejemplo26b
Usted es mi cliente 3
(----- aquí cerramos el servidor -----)
C:\java\curso>java Ejemplo26b
java.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)
<BR>
</FONT>
</PRE>
<P>
Esto es todo por ahora. El ejemplo fue lo más sencillo
posible, pero mediante el mismo método el servidor y los
clientes pueden intercambiar datos escribiendo en ambas direcciones.
Inclusive, el servidor puede correr en una máquina y los
clientes en otras; además, si bien en este caso utilizamos
aplicaciones standalone, se pueden utilizar applets.
<P>
Por ejemplo, una aplicación servidora puede correr constantemente
en un server de Internet (por ejemplo, para buscar datos en una
base de datos) y diferentes clientes en distintas máquinas,
posioblemente applets Java, pueden conectarse a ella y consultarla.
<BR>
<BR>
<BR>
<P>
Jorge Bourdette
<P>
<A HREF="mailto:jpb@amarillas.com" >jpb@amarillas.com</A><BR>
</BODY>
</HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -