miércoles, 25 de febrero de 2009

EJECUTAR TCP/IP EN Windows '95

Las indicaciones que se proporcionan a continuación, van a permitirnos fijar los parámetros de Windows '95 para que se puedan ejecutar programas cliente y servidor, sin necesidad de que el ordenador en el cual se está ejecutando Windows '95 esté conectado a una red de área local. Esto puede resultar útil para mucha gente que está probando Java en su casa y no dispone de red, o incluso para aquellos programadores o estudiosos que quieren probar sus nuevos programas distribuidos pero no disponen de red o de Internet.

Advertencia: Si los siguientes parámetros se van a fijar en un ordenador portátil que en ocasiones sí se conecte a una red, sería conveniente anotar los parámetros actuales de la configuración de Windows '95, para que sean fácilmente recuperables cuando este ordenador se vuelva a conectar a la red.

Configuración del TCP/IP de Windows '95

Hay que seguir los pasos que vamos a relatar a continuación, suponemos que se está ejecutando la versión española de Windows '95, en otras versiones puede que las opciones tengan nombre diferente:

1. En el Panel de Control, seleccionar Red
2. Picar Agregar, luego Protocolo y luego Agregar
3. Seleccionar Microsoft y luego TCP/IP y picar en Aceptar
4. En este momento probablemente se solicite la introducción de los discos de Windows '95, o del CD-ROM
5. Seleccionar la pestaña Configuración de la ventana Red
6. Seleccionar TCP/IP en la lista que aparece y picar Propiedades
7. Seleccionar la pestaña Dirección IP
o Crearse una dirección IP, como por ejemplo: 102.102.102.102
o Crearse una Máscara de subred, como: 255.255.255.0
8. Seleccionar la pestaña Configuración DNS y desactivar DNS
9. Los valores correspondientes a las otras cuatro pestañas pueden dejarse los que hay por defecto
10. Picar Aceptar
11. (Opcional) Seleccionar la pestaña Identificación de la ventana Red
12. (Opcional) Introducir un nombre para el ordenador, como por ejemplo: breogan
13. (Opcional) Picar Aceptar

Crear una entrada en la "red"

1. Editar el fichero hosts.sam que está en el directorio de Windows
2. Al final del fichero incorporar la dirección IP y el nombre del ordenador que se han introducido antes, en nuestro caso: 102.102.102.102 breogan
3. Asegurarse de que la dirección IP y el nombre coinciden con la dirección IP que se ha fijado en el paso 7a de antes y que el nombre es el mismo que el indicado en el paso 12 anterior
4. Salvar el fichero con el nombre "hosts" y reiniciar Windows '95
Comprobación de la red
1. Abrir una sesión MS-DOS
2. Teclear "ping breogan"
3. Debería aparecer:
4. Pinging breogan [102.102.102.102] with 32 bytes of data:
5. Reply from 102.102.102.102: bytes=32 time=1ms TTL=32
6. Reply from 102.102.102.102: bytes=32 time<10ms TTL=32
7. Reply from 102.102.102.102: bytes=32 time<10ms TTL=32
8. Reply from 102.102.102.102: bytes=32 time<10ms TTL=32
9. Teclear "tracert 102.102.102.102"
10. Debería aparecer:
11. Tracing route to 102.102.102.102 over a maximum of 30 hops
12. 1 <10 ms 1 ms <10 ms 102.102.102.102
13. Trace complete.

En este instante, si todo ha ido bien, el ordenador está listo para funcionar como si estuviera en red. Dos o más programas que se comuniquen en red a través de sockets debería poder ejecutarse ahora dentro de los dominios del ordenador que acabamos de configurar

Problemas más frecuentes

Los tres problemas que pueden presentarse cuando intentemos comprobar el funcionamiento correcto de la red interna que acabamos de montar son:

Cuando hacemos "ping" obtenemos "Bad IP address breogan"
Intentar teclear "ping 102.102.102.102". Si ahora sí se obtiene réplica, la causa del problema es que el los pasos 12 de la Configuración y 3 de la Creación de la entrada en la tabla de hosts, no se ha introducido correctamente el nombre de la máquina. Comprobar esos pasos y que todo coincide.
El programa cliente o el servidor fallan al intentar el "connect"
La causa podría estar en que se produzca un fallo por fichero no encontrado en el directorio Windows/System de las librerías WINSOCK.DLL o WSOCK32.DLL. Muchos programas que se utilizan en Internet reemplazan estos ficheros cuando se instalan. Asegurarse de que están estos ficheros y que son los originales que vienen con la distribución de Windows '95.
El programa servidor dice que no puede "bind" a un socket
Esto sucede porque tiene el DNS activado y no puede encontrar ese DNS o servidor de direcciones, porque estamos solos en la red. Asegurarse de que en el paso 8 de la Configuración la opción de DNS está deshabilitada.

CLASES UTILES EN COMUNICACIONES

Vamos a exponer otras clases que resultan útiles cuando estamos desarrollando programas de comunicaciones, aparte de las que ya se han visto. El problema es que la mayoría de estas clases se prestan a discusión, porque se encuentran bajo el directorio sun. Esto quiere decir que son implementaciones Solaris y, por tanto, específicas del Unix Solaris. Además su API no está garantizada, pudiendo cambiar. Pero, a pesar de todo, resultan muy interesantes y vamos a comentar un grupo de ellas solamente que se encuentran en el paquete sun.net
Socket

Es el objeto básico en toda comunicación a través de Internet, bajo el protocolo TCP. Esta clase proporciona métodos para la entrada/salida a través de streams que hacen la lectura y escritura a través de sockets muy sencilla.

ServerSocket

Es un objeto utilizado en las aplicaciones servidor para escuchar las peticiones que realicen los clientes conectados a ese servidor. Este objeto no realiza el servicio, sino que crea un objeto Socket en función del cliente para realizar toda la comunicación a través de él.
DatagramSocket

La clase de sockets datagrama puede ser utilizada para implementar datagramas no fiables (sockets UDP), no ordenados. Aunque la comunicación por estos sockets es muy rápida porque no hay que perder tiempo estableciendo la conexión entre cliente y servidor.
DatagramPacket

Clase que representa un paquete datagrama conteniendo información de paquete, longitud de paquete, direcciones Internet y números de puerto.
MulticastSocket

Clase utilizada para crear una versión multicast de las clase socket datagrama. Múltiples clientes/servidores pueden transmitir a un grupo multicast (un grupo de direcciones IP compartiendo el mismo número de puerto).

NetworkServer

Una clase creada para implementar métodos y variables utilizadas en la creación de un servidor TCP/IP.
NetworkClient
Una clase creada para implementar métodos y variables utilizadas en la creación de un cliente TCP/IP.
SocketImpl
Es un Interface que nos permite crearnos nuestro propio modelo de comunicación. Tendremos que implementar sus métodos cuando la usemos. Si vamos a desarrollar una aplicación con requerimientos especiales de comunicaciones, como pueden se la implementación de un cortafuegos (TCP es un protocolo no seguro), o acceder a equipos especiales (como un lector de código de barras o un GPS diferencial), necesitaremos nuestra propia clase Socket.
Vamos a ver un ejemplo de utilización, presentando un sencillo ejemplo, servidorUDP.java, de implementación de sockets UDP utilizando la clase DatagramSocket.
import java.net.*;
import java.io.*;
import sun.net.*;

// Implementación del servidor de datagramas UDP. Envía una cadena
// tras petición
//
class servidorUDP {
public static void main( String args[] ) {
DatagramSocket s = (DatagramSocket)null;
DatagramPacket enviap,recibep;
byte ibuffer[] = new byte[100];
String cadena = "Hola Tutorial de Java!\n";
InetAddress IP = (InetAddress)null;
int longitud = sendString.length();
int puertoEnvio = 4321;
int puertoRecep = 4322;
int puertoRemoto;

// Intentamos conseguir la dirección IP del host
try {
IP = InetAddress.getByName( "bregogan" );
} catch( UnknownHostException e ) {
System.out.println( "No encuentro al host breogan" );
System.exit( -1 );
}

// Establecemos el servidor para escuchar en el socket 4322
try {
s = new DatagramSocket( puertoRecep );
} catch( SocketException e ) {
System.out.println( "Error - "+e.toString() );
}

// Creamos un paquete de solicitud en el cliente
// y nos quedamos esperando a sus peticiones
recibep = new DatagramPacket( ibuffer,longitud );
try {
s.receive( recibep );
} catch( IOException e ) {
System.out.println( "Error - "+e.toString() );
}

// Creamos un paquete para enviar al cliente y lo enviamos
sendString.getBytes( 0,longitud,ibuffer,0 );
enviap = new DatagramPacket( ibuffer,longitud,IP,puertoEnvio );
try {
s.send( enviap );
} catch( IOException e ) {
System.out.println( "Error - "+e.toString() );
System.exit( -1 );
}

// Cerramos el socket
s.close();
}
}
Y también vamos a implementar el cliente, clienteUDP.java, del socket UDP correspondiente al servidor que acabamos de presentar:
import java.net.*;
import java.io.*;
import sun.net.*;

// Implementación del cliente de datagramas UDP. Devuelve la salida
// de los servidores
//
class clienteUDP {
public static void main( String args[] ) {
int longitud = 100;
DatagramSocket s = (DatagramSocket)null;
DatagramPacket enviap,recibep;
byte ibuffer[] = new byte[100];
InetAddress IP = (InetAddress)null;
int puertoEnvio = 4321;
int puertoRecep = 4322;

// Abre una conexión y establece el cliente para recibir
// una petición en el socket 4321
try {
s = new DatagramSocket( puertoRecep );
} catch( SocketException e ) {
System.out.println( "Error - "+e.toString() );
}

// Crea una petición para enviar bytes. Intenta conseguir
// la dirección IP del host
try {
IP = InetAddress.getByName( "depserver" );
} catch( UnknownHostException e ) {
System.out.println( "No encuentro el host depserver" );
System.exit( -1 );
}

// Envía una petición para que responda el servidor
try {
enviap = new DatagramPacket( ibuffer,ibuffer.length,
IP,4322 );
s.send( enviap );
} catch( IOException e ) {
System.out.println( "Error - "+e.toString() );
}

// Consigue un controlador de fichero de entrada del socket y lee
// dicha entrada. Creamos un paquete descriptor para recibir el
// paquete UDP
recibep = new DatagramPacket( ibuffer,longitud );

// Espera a recibir un paquete
try {
s.receive( recibep );
} catch( IOException e ) {
System.out.println( "Error - "+e.toString() );
System.exit( -1 );
}

// Imprimimos los resultados de lo que conseguimos
System.out.println( "Recibido: "+recibep.getLength()+" bytes" );
String datos = new String( recibep.getData(),0 );
System.out.println( "Datos: "+datos );
System.out.println( "Recibido por puerto: "+recibep.getPort() );

// Cerramos la conexión y abandonamos
s.close();
}
}
La salida que se producirá cuando ejecutemos primero el servidor y luego el cliente será la misma que reproducimos a continuación:
%java clienteUDP
Recibido: 17 bytes
Datos: Hola Tutorial de Java!

Recibido por puerto: 4322

No hay comentarios:

Publicar un comentario