carrera: desarrollo de software semestre 05 · carrera: desarrollo de software semestre 05 programa...

22
Programación orientada a objetos III Unidad 3. Programación en red 1 Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación en red Clave: 16142524 Universidad Abierta y a Distancia de México

Upload: others

Post on 12-Oct-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

1

Carrera: Desarrollo de software

Semestre 05

Programa de la asignatura:

Programación orientada a objetos III

Unidad 3. Programación en red

Clave:

16142524

Universidad Abierta y a Distancia de México

Page 2: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

2

Índice

PRESENTACIÓN DE LA UNIDAD ......................................................................................... 3

PROPÓSITOS DE LA UNIDAD ............................................................................................. 3

COMPETENCIA ESPECÍFICA .............................................................................................. 3

TEMARIO DE LA UNIDAD..................................................................................................... 3

TEMA 3.1. MODELO CLIENTE-SERVIDOR .......................................................................... 4

TEMA 3.2. STREAMS ............................................................................................................ 5

CIERRE DE LA UNIDAD ..................................................................................................... 21

PARA SABER MÁS… .......................................................................................................... 21

FUENTES DE CONSULTA .................................................................................................. 22

Page 3: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

3

Presentación de la unidad

Hoy en día el uso de las computadoras requiere un inevitable intercambio de información

con otros equipos, sea para revisar correos electrónicos, chatear, etc. Para poder realizar

este intercambio de información es necesario que se realicen programas que permitan dicho

intercambio, con este fin se cuenta con sockets que son los elementos que permiten el paso

de información entre equipos diferentes conectados a una misma red.

En esta tercera unidad de la materia Programación orientada a objetos III, analizarás el

modo de trabajo del modelo cliente-servidor, así como el funcionamiento de los streams; al

final se unirán los temas previos para realizar el manejo de sockets para crear programas

que trabajen en red, de manera que se puedan conectar varias computadoras para

intercambiar información.

Cabe señalar que la Unidad 3. Programación en red, representa el cierre de la asignatura

Programación orientada a objetos III, por lo tanto, es necesario que recuperes los

contenidos de unidades anteriores y de la Programación orientadas a objetos I y II, pues,

ello te servirá para avanzar en cada uno de los logros que componen a la competencia

específica de la unidad.

Propósitos de la unidad

En esta unidad lograrás:

Identificar el modelo de comunicación cliente–servidor.

Distinguir el funcionamiento y la estructura de los streams.

Crear programas en red mediante el uso de sockets.

Competencia específica

Generar programas en red para el intercambio de información entre un cliente y un servidor,

mediante la manipulación de sockets.

Temario de la unidad

3. Programación en red

3.1. Modelo cliente-servidor

3.1.1. Cliente

3.1.2. Servidor

3.2. Streams

3.2.1. De entrada

3.2.2. De salida

Page 4: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

4

3.3. Sockets

3.3.1. Apertura

3.3.2. Cierre

3. Programación en red

Hoy en día, la inmensa mayoría de las computadoras que existen intercambian información

unas con otras; para intercambiar información, ya sea personal, comercial, o sólo por

convivencia, las personas se encuentran en constante comunicación y, en dicha actividad,

las computadoras son de gran ayuda, para permitir una instantánea comunicación sin

importar las distancias. En el presente tema revisaremos lo que es la programación en red,

con lo que aprenderás a realizar programas que realicen un intercambio de información

entre computadoras.

Tema 3.1. Modelo cliente-servidor

En la actualidad el intercambio de información entre distintos equipos de cómputo se ha

vuelto muy importante, ya que una computadora aislada difícilmente será de alta utilidad

para un usuario. Para lograr la comunicación entre computadoras es importante realizar un

intercambio de información entre éstas, de manera tal que debemos contar con una

computadora que envié una petición de información (cliente) a otra, que al recibir la petición

le responda con la información solicitada (servidor), tal como se muestra en la siguiente

imagen. De esta manera se logra tener un flujo de datos entre ambos equipos, con lo que se

logra el intercambio de información.

Figura. Modelo cliente-servidor

Para lograr realizar esto, Java ha desarrollado clases que permiten la manipulación de los

puertos de las computadoras que permitan esta comunicación en red entre los diferentes

equipos.

Page 5: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

5

Típicamente un cliente se reconoce como tal por ser quien comienza el intercambio de

información al realizar una petición al servidor, mientras que el servidor espera a que los

clientes le estén solicitando información para responderles.

Para que conozcas más a fondo el modelo de intercambio de información cliente-servidor

revisa el siguiente material:

En el texto de Niemeyer, P. (2000, p. 258) se cuenta con una breve introducción a la

programación en red, donde encontrarás la descripción de lo que es un cliente y lo

que es un servidor, recordándonos que la principal diferencia es que el cliente puede

crear sockets para iniciar la comunicación, mientras que el servidor está a la espera

de peticiones.

Por su parte Hervás, C. (2004 p. 1) nos muestra una descripción de lo que es el

modelo cliente-servidor, donde se indica que los clientes inician las conexiones a un

puerto conocido del servidor siempre que esté disponible un puerto del cliente para

realizar el intercambio de información.

Ahora bien, sólo resta apuntar que para poder realizar un programa que trabaje en red

deberás ajustarte al modelo cliente-servidor para el intercambio de información; por lo que,

como es de esperarse, se deberán crear dos programas, uno que funcionará en el cliente y

otro en el servidor. Más adelante, cuando veamos el tema de sockets, veremos un ejemplo

para crear un programa cliente y uno servidor, por el momento lo importante es que

comprendas este modelo de comunicación.

Para concluir este tema, realiza la Actividad 1. Cliente-servidor, que se presenta en el

documento: Actividades de la unidad 3, donde identificarás el modelo de comunicación

cliente-servidor, así como identificar el papel que juega cada uno para la comunicación en

red.

Tema 3.2. Streams

Para continuar con el tema, se revisará como al pretender mostrar u obtener alguna

información de un lugar externo, es necesario que el programa cree un flujo de datos para

poder manejarlos (algo parecido al canal de comunicación que se abre para conectarse a

una base de datos). Por lo tanto, hay un flujo de entrada que recibe los datos desde el

exterior del programa y un flujo de salida que envía los datos hacia el ordenador u otro

dispositivo de almacenamiento.

Los streams tal como menciona Abián (2004, p.18) “son tuberías o canales de

comunicaciones: tienen dos extremos entre los cuales fluyen los datos de manera continua”.

En esta misma obra puede verse en Abián (2004, p. 101) una clara descripción sobre lo que

son los streams y la distinción entre los flujos que toman datos desde una fuente externa

Page 6: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

6

hacia el programa (stream de entrada) y por otra parte están los flujos que mueven datos

desde un programa hacía algún receptor externo (stream de salida).

En Flujos de datos en Java de FIC (2007, p. 33-36) encontrarás la descripción de los

procesos para la lectura y escritura de datos mediante el manejo de streams. Los cuales

pueden ilustrarse mediante las siguientes imágenes, donde en un equipo de origen,

mediante un stream se envía un flujo de información a un programa, que se encuentra

alojado en otro equipo diferente al origen y se puede regresar mediante otro stream la

información de respuesta.

Figura. Flujos de datos en Java.

Recuperado de: FIC (2007).

Para el manejo flujos de entrada/salida, Java nos proporciona dos tipos de flujos posibles,

los de byte y los de caracteres. Los cuales se describen a continuación:

Flujo de bytes (ByteStreams): Nos proporciona un medio adecuado para el manejo

de entradas y salidas de bytes y su uso lógicamente está orientado a la lectura y

escritura de datos binarios (Suarez, 2001).

Flujo de caracteres (CharacterStreams): Proporciona un medio adecuado para el

manejo de entradas y salidas de caracteres (Suarez, 2001).

En Flujos de datos en Java de FIC (2007, p. 36), encontrarás la descripción de los procesos

para la lectura y escritura de datos mediante el manejo de streams.

Page 7: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

7

Para conocer más a fondo las clases que controlan la entrada y salida de datos de un

programa revisa los siguientes textos1:

En la siguiente liga de Oracle (2012), encontrarás la descripción del uso de flujos de

bytes, los cuales son utilizados para cuando la entrada/salida de datos consta de

datos representados mediante bytes. Ahí encontrarás su descripción, así como la

explicación de su uso, además se presenta también el código mediante el cual se

crea el stream y se lee su contenido. Por lo tanto ingresa a:

http://docs.oracle.com/javase/tutorial/essential/io/bytestreams.html

En la liga de Oracle (2012) encontrarás la descripción del uso de flujos basados en

caracteres, en este material encontrarás una explicación de dichos streams; así

mismo, verás la explicación de la sintaxis para crearlos y también para leerlos. Así

pues, ingresa a:

http://docs.oracle.com/javase/tutorial/essential/io/charstreams.html

Para concluir este tema, realiza la Actividad 2. Programa con streams, que se presenta en el

documento: Actividades de la Unidad 3, donde distinguirás el funcionamiento y la estructura

de los streams para realizar programas en red.

Tema 3.3. Sockets

Para crear un puente entre dos equipos que pretenden conectarse se requiere de los

siguientes elementos: los sockets, que son básicamente cada uno de los extremos (en cada

equipo/computadora) que generan la comunicación entre dos programas que se estarán

comunicando en red. Por su parte los sockets requieren de conocerla dirección IP del equipo

con el que se entablará la comunicación, además del puerto al que se conectará, pues bien

los puertos son las conexiones físicas que tiene un equipo para conectarse a la red.

Como se mencionó en el tema de Modelo cliente-servidor, el cliente es quien comienza la

comunicación realizando una petición al servidor, por lo que el cliente ya debe conocer el

nombre de host de la máquina en que se ejecuta el servidor (IP) y el número de puerto en el

que escucha el servidor. Para realizar una solicitud de conexión, el cliente intenta reunirse con

el servidor en la máquina del servidor y el puerto. El cliente también debe identificarse ante el

servidor. Tal como se muestra en las siguientes imágenes, primero el cliente envía una

petición al servidor y, en la segunda imagen, se muestra como el servidor le responde al

cliente, en ambos casos la comunicación se establece en un punto particular, el puerto.

1 Para profundizar en el tema y cumplir con las tareas de la unidad, ingresa a la sección de materiales de apoyo de la unidad. Consulta los textos de la unidad que se agregan en formato PDF

Page 8: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

8

Figura. Comunicación cliente-servidor

De tal manera que un socket se comunica al equipo al que se quiere conectar mediante un

puerto.

El ciclo de vida de un canal de comunicación (socket), está determinado por tres fases, Díaz

(2011) las enlista de la siguiente manera:

Creación y apertura del socket.

Lectura y/o escritura, recepción y/o envío de datos por el socket.

Destrucción, cierre del socket.

Ahora, revisa Programación con Sockets en FIC (2007, p. 13-15), donde encontrarás la

descripción del proceso de conexión entre un cliente y un servidor mediante sockets.

Revisando este material lograrás comprender el proceso de la conexión.

Para identificar las clases necesarias para la programación en red revisa Martínez (2000, p.

10), ahí encontrarás el nombre y descripción de las principales clases requeridas para la

creación de programas que funcionen en red y logren intercambiar información entre

diferentes equipos.

En la siguiente imagen puedes ver el esquema de conexión mediante sockets y el flujo de

streams para que se realicen un programa en red que intercambie información entre

equipos.

Page 9: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

9

Figura. Conexión mediante sockets. Recuperada de (Díaz, 2011, p. 7)

Para complementar la información revisa The Java Tutorials, la lección All About Sockets,

en Oracle (2012), donde encontrarás el tema de sockets completo, desde las explicaciones

teóricas respecto al tema, así como ejemplos básicos para la creación de programas en red,

resulta muy conveniente que revises el material completo, pues Oracle es dueño del

lenguaje Java, por lo que sus manuales contienen las referencias más precisas. Por lo tanto,

Ingresa a la liga:

http://docs.oracle.com/javase/tutorial/networking/sockets/index.html

A continuación se te presentan los bloques de código que muestran la creación de un

programa en red, verás dos clases: una que se encargará de la aplicación que maneja el

servidor, la otra clase es la encargada del cliente. Analiza detalladamente los códigos para

que comprendas su aplicación, todo el código se encuentra comentado para que sea más

fácil de digerirlo, se sugiere también que ejecutes el código presentado para que analices

los resultados. Pon mucha atención en los comentarios para que identifiques fácilmente el

funcionamiento de la sintaxis presentada.

Ejemplo de código 1. Clase que controla el servidor import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import javax.swing.JOptionPane;

/**

* Esta clase representa el programa servidor.

*/

public class Aplicacion_Servidor extends javax.swing.JFrame {

/**

* Creates new form Aplicacion_Servidor

*/

public Aplicacion_Servidor() {

Page 10: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

10

initComponents();

}

SuppressWarnings("unchecked")

// <editor-fold defaultstate="collapsed" desc="Generated Code">

private void initComponents() {

/* En esta sección se tienen los elementos que compondrán la apariencia gráfica

de la aplicación, declaraciones y acomodos en la pantalla */

txtPuertoSocket = new javax.swing.JTextField();

lblPuertoSocket = new javax.swing.JLabel();

btnAbrirPuerto = new javax.swing.JButton();

btnCerrarPuerto = new javax.swing.JButton();

jPanel1 = new javax.swing.JPanel();

jScrollPane1 = new javax.swing.JScrollPane();

txtaDatosEntrantes = new javax.swing.JTextArea();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

setTitle("Comunicacion con Sockets - Servidor");

txtPuertoSocket.setText("12345");

lblPuertoSocket.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

lblPuertoSocket.setText("Puerto:");

btnAbrirPuerto.setText("Abrir");

btnAbrirPuerto.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) {

btnAbrirPuertoActionPerformed(evt);

}

});

btnCerrarPuerto.setText("Cerrar");

btnCerrarPuerto.setEnabled(false);

btnCerrarPuerto.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) {

btnCerrarPuertoActionPerformed(evt);

}

});

jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Datos

Recibidos"));

jPanel1.setEnabled(false);

jPanel1.setLayout(new java.awt.BorderLayout());

txtaDatosEntrantes.setColumns(20);

txtaDatosEntrantes.setEditable(false);

txtaDatosEntrantes.setRows(5);

txtaDatosEntrantes.setEnabled(false);

jScrollPane1.setViewportView(txtaDatosEntrantes);

jPanel1.add(jScrollPane1, java.awt.BorderLayout.CENTER);

javax.swing.GroupLayout layout = new

javax.swing.GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addContainerGap()

.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addComponent(lblPuertoSocket,

javax.swing.GroupLayout.PREFERRED_SIZE, 74,

javax.swing.GroupLayout.PREFERRED_SIZE)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

.addComponent(txtPuertoSocket,

javax.swing.GroupLayout.PREFERRED_SIZE, 111,

Page 11: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

11

javax.swing.GroupLayout.PREFERRED_SIZE)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

.addComponent(btnAbrirPuerto)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

.addComponent(btnCerrarPuerto)

.addGap(0, 40, Short.MAX_VALUE))

.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE,

javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))

.addContainerGap())

);

layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new

java.awt.Component[] {btnAbrirPuerto, btnCerrarPuerto});

layout.setVerticalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addContainerGap()

.addGroup(layout.createParallelGroup(

javax.swing.GroupLayout.Alignment.BASELINE)

.addComponent(txtPuertoSocket,

javax.swing.GroupLayout.PREFERRED_SIZE,

javax.swing.GroupLayout.DEFAULT_SIZE,

javax.swing.GroupLayout.PREFERRED_SIZE)

.addComponent(lblPuertoSocket)

.addComponent(btnAbrirPuerto)

.addComponent(btnCerrarPuerto))

.addPreferredGap(

javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)

.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 162,

Short.MAX_VALUE)

.addContainerGap())

);

java.awt.Dimension screenSize =

java.awt.Toolkit.getDefaultToolkit().getScreenSize();

setBounds((screenSize.width-403)/2, (screenSize.height-253)/2, 403, 253);

}// </editor-fold>

/* Aquí se termina la creación de la apariencia gráfica */

/* El boton de Abrir Puerto será el que mande a llamar al método abrirSocket */

private void btnAbrirPuertoActionPerformed(java.awt.event.ActionEvent evt) {

// TODO add your handling code here:

abrirSocket();

}

/* El boto Cerrar Puerto manda a llamar al método cerrarSocket */

private void btnCerrarPuertoActionPerformed(java.awt.event.ActionEvent evt) {

// TODO add your handling code here:

cerrarSocket();

}

/**

* El método principal invoca a que se ejecute la aplicación del servidor */

*/

public static void main(String args[]) {

java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {

new Aplicacion_Servidor().setVisible(true);

}

});

}

/* A continuación se presenta el método de abrirSocket */

public void abrirSocket()

{

String msg = null;

Page 12: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

12

int puerto = 0;

try

{

//Establecemos el puerto a través del cual se abrirá el socket.

puerto = Integer.valueOf(txtPuertoSocket.getText().trim());

//Se asigna ese Puerto al socket creado

serverSocket = new ServerSocket(puerto);

//Habilitamos y deshabilitamos controles de la interfaz de usuario

//para evitar un funcionamiento indeseado.

habilitarControlesAperturaDeSocket(false);

//Notificamos al usuario que se ha creado un socket.

msg ="Socket creado exitosamente en el puerto " + puerto + "." +

"\n\nEl programa quedará bloqueado hasta que se establezca " +

"alguna conexión con un cliente.";

JOptionPane.showMessageDialog(this, msg, "Socket creado.",

JOptionPane.INFORMATION_MESSAGE);

//Esperamos a que un cliente se conecte.

cliente = serverSocket.accept();

//Obtenemos los objetos para poder leer y escribir a través

//del socket

entrada = cliente.getInputStream();

salida = cliente.getOutputStream();

lector = new DataInputStream(entrada);

escritor = new DataOutputStream(salida);

leerDatosDelCliente();

}

//Si el usuario captura un número de puerto incorrecto se captura el error

y se le notifica al usuario.

catch (NumberFormatException nfe)

{

msg = "El numero de puerto debe ser un numero entero mayor a 0 " +

"y menor a 65535.";

JOptionPane.showMessageDialog(this, msg,

"Numero de puerto incorrecto",

JOptionPane.ERROR_MESSAGE);

nfe.printStackTrace();

}

//Si el usuario intenta acceder a un numero de puerto no disponible se

captura el error y se le notifica al usuario.

catch (Exception e)

{

msg = "Error al intentar abrir socket en el puerto " + puerto +

"\n\nProbablemente el puerto esté en uso o el firewall " +

"de su equipo impidio su apertura.";

JOptionPane.showMessageDialog(this, msg, "Error",

JOptionPane.ERROR_MESSAGE);

}

} //Termina el método se abrirSocket

// Inicia el método de cerrarSocket

public void cerrarSocket()

{

String msg = null;

try

{

leyendo = false;

// Se está en espera de recibir comunicación por parte del cliente.

if (cliente != null)

{

//Con esto se cierra la conexión con el cliente.

cliente.close();

//Con esto se cierra el socket servidor, ya no atendemos más

conexiones.

serverSocket.close();

Page 13: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

13

cliente = null;

serverSocket = null;

habilitarControlesAperturaDeSocket(true);

}

}

/* En el caso de que no se pueda cerrar el socket se captura la excepción y

se cierra el sistema */

catch (Exception e)

{

msg = "Error al intentar cerrar el socket.\n\n" +

"El sistema se cerrara después de este cuadro de dialogo.";

JOptionPane.showMessageDialog(this, msg, "Error",

JOptionPane.ERROR_MESSAGE);

e.printStackTrace();

}

}

/* El siguiente es el método para en caso de abrir el socket se habiliten los

componentes gráficos o se deshabiliten según sea el estado del socket */

public void habilitarControlesAperturaDeSocket(boolean value)

{

//Habilitamos los controles para la apertura del socket

lblPuertoSocket.setEnabled(value);

txtPuertoSocket.setEnabled(value);

btnAbrirPuerto.setEnabled(value);

//Deshabilitamos los controles de recepcion de datos y cierre

btnCerrarPuerto.setEnabled(!value);

txtaDatosEntrantes.setEnabled(!value);

jPanel1.setEnabled(!value);

}

/* El siguiente método es para leer los datos que el cliente envía hacia el

servidor */

public void leerDatosDelCliente()

{

Thread t = null;

/*Creamos un objeto para leer datos del cliente indefinidamente

a través de un hilo. La interface Runnable solamente declara una función miembro denominada run, que han de definir las clases que implementen este interface

*/

Runnable r = new Runnable()

{

/* Se declara entonces la función run, que implementa la interface

Runnable*/

Override

public void run()

{

if (leyendo)

return;

leyendo = true;

while (leyendo)

{

/*Mientras se está leyendo se toman los datos que se están

introduciendo, en la caja de texto txtaDatosEntrantes*/

try

{

txtaDatosEntrantes.setText(txtaDatosEntrantes.getText() +

"\n" +

lector.readUTF());

if (txtaDatosEntrantes.getText().length() > 0)

txtaDatosEntrantes.setCaretPosition(

txtaDatosEntrantes.getText().length() - 1);

}

catch (Exception e)

{

e.printStackTrace();

}

Page 14: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

14

}

}

};

t = new Thread(r);

//Se inicializa el hilo de lectura

t.start();

}

// Variables declaration - do not modify

private javax.swing.JButton btnAbrirPuerto;

private javax.swing.JButton btnCerrarPuerto;

private javax.swing.JPanel jPanel1;

private javax.swing.JScrollPane jScrollPane1;

private javax.swing.JLabel lblPuertoSocket;

private javax.swing.JTextField txtPuertoSocket;

private javax.swing.JTextArea txtaDatosEntrantes;

// End of variables declaration

//Socket Servidor que aceptara conexiones de clientes

ServerSocket serverSocket;

//Objeto que se comunicará con los clientes para enviar y recibir datos.

Socket cliente;

//Objetos que permitiran leer y escribir flujos de bits través del socket.

InputStream entrada;

OutputStream salida;

//Objetos que permitiran leer valores de algun tipo desde el socket.

DataInputStream lector;

DataOutputStream escritor;

//Esta variable sirve para mantener o cerrar el ciclo de lectura de datos

//desde el cliente

boolean leyendo;

}

Ejemplo de código 2. Clase que controla el cliente

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import javax.swing.JOptionPane;

/**

* Esta clase representa el programa cliente.

*/

public class Aplicacion_Cliente extends javax.swing.JFrame {

/**

* Creates new form Aplicacion_Servidor

*/

public Aplicacion_Cliente() {

initComponents();

}

SuppressWarnings("unchecked")

Page 15: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

15

// <editor-fold defaultstate="collapsed" desc="Generated Code">

private void initComponents() {

/* En esta sección se tienen los elementos que compondrán la apariencia grafica

de la aplicación, declaraciones y acomodos en la pantalla */

txtPuertoSocket = new javax.swing.JTextField();

lblPuertoSocket = new javax.swing.JLabel();

btnAbrirPuerto = new javax.swing.JButton();

btnCerrarPuerto = new javax.swing.JButton();

lblIp = new javax.swing.JLabel();

txtIp = new javax.swing.JTextField();

txtDatos = new javax.swing.JTextField();

btnEnviarDatos = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

setTitle("Comunicacion con Sockets - Cliente");

txtPuertoSocket.setText("12345");

lblPuertoSocket.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

lblPuertoSocket.setText("Puerto:");

btnAbrirPuerto.setText("Abrir");

btnAbrirPuerto.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) {

btnAbrirPuertoActionPerformed(evt);

}

});

btnCerrarPuerto.setText("Cerrar");

btnCerrarPuerto.setEnabled(false);

lblIp.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

lblIp.setText("Ip:");

txtIp.setText("127.0.0.1");

txtDatos.addKeyListener(new java.awt.event.KeyAdapter() {

public void keyReleased(java.awt.event.KeyEvent evt) {

txtDatosKeyReleased(evt);

}

});

btnEnviarDatos.setText("Enviar");

btnEnviarDatos.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(java.awt.event.ActionEvent evt) {

btnEnviarDatosActionPerformed(evt);

}

});

javax.swing.GroupLayout layout = new

javax.swing.GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addContainerGap()

.addGroup(layout.createParallelGroup(

Page 16: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

16

javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addGroup(layout.createParallelGroup(

javax.swing.GroupLayout.Alignment.LEADING, false)

.addComponent(lblPuertoSocket,

javax.swing.GroupLayout.DEFAULT_SIZE,

74, Short.MAX_VALUE)

.addComponent(lblIp,

javax.swing.GroupLayout.DEFAULT_SIZE,

javax.swing.GroupLayout.DEFAULT_SIZE,

Short.MAX_VALUE))

.addPreferredGap(

javax.swing.LayoutStyle.ComponentPlacement.RELATED)

.addGroup(layout.createParallelGroup(

javax.swing.GroupLayout.Alignment.LEADING,

false)

.addGroup(layout.createSequentialGroup()

.addComponent(txtPuertoSocket,

javax.swing.GroupLayout.PREFERRED_SIZE,

111,

javax.swing.GroupLayout.PREFERRED_SIZE)

.addPreferredGap(

javax.swing.LayoutStyle.ComponentPlacement.RELATED)

.addComponent(btnAbrirPuerto)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

.addComponent(btnCerrarPuerto))

.addComponent(txtIp)))

.addGroup(layout.createSequentialGroup()

.addComponent(txtDatos,

javax.swing.GroupLayout.PREFERRED_SIZE, 258,

javax.swing.GroupLayout.PREFERRED_SIZE)

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

.addComponent(btnEnviarDatos)))

.addContainerGap(49, Short.MAX_VALUE))

);

layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new

Page 17: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

17

java.awt.Component[] {btnAbrirPuerto, btnCerrarPuerto});

layout.setVerticalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,

Short.MAX_VALUE)

.addGroup(layout.createParallelGroup(

javax.swing.GroupLayout.Alignment.BASELINE)

.addComponent(lblIp)

.addComponent(txtIp, javax.swing.GroupLayout.PREFERRED_SIZE,

javax.swing.GroupLayout.DEFAULT_SIZE,

javax.swing.GroupLayout.PREFERRED_SIZE))

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

.addGroup(layout.createParallelGroup(

javax.swing.GroupLayout.Alignment.BASELINE)

.addComponent(txtPuertoSocket,

javax.swing.GroupLayout.PREFERRED_SIZE,

javax.swing.GroupLayout.DEFAULT_SIZE,

javax.swing.GroupLayout.PREFERRED_SIZE)

.addComponent(lblPuertoSocket)

.addComponent(btnAbrirPuerto)

.addComponent(btnCerrarPuerto))

.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)

.addGroup(layout.createParallelGroup(

javax.swing.GroupLayout.Alignment.BASELINE)

.addComponent(txtDatos, javax.swing.GroupLayout.PREFERRED_SIZE,

javax.swing.GroupLayout.DEFAULT_SIZE,

javax.swing.GroupLayout.PREFERRED_SIZE)

.addComponent(btnEnviarDatos))

.addGap(179, 179, 179))

);

java.awt.Dimension screenSize =

java.awt.Toolkit.getDefaultToolkit().getScreenSize();

setBounds((screenSize.width-402)/2, (screenSize.height-145)/2, 402, 145);

}// </editor-fold>

/* Aquí se termina la creación de la apariencia gráfica */

/* El boton de Abrir Puerto será el que mande a llamar al método

abrirConexionConElServidor */

private void btnAbrirPuertoActionPerformed(java.awt.event.ActionEvent evt) {

// TODO add your handling code here:

Page 18: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

18

abrirConexionConElServidor();

}

/* El botón de Enviar Datos será el que mande a llamar al método enviarDatos */

private void btnEnviarDatosActionPerformed(java.awt.event.ActionEvent evt) {

// TODO add your handling code here:

enviarDatos();

}

/* Se tiene un manejo de evento sobre txtDatos para estar escuchando cada una de las

teclas que se oprimen */

private void txtDatosKeyReleased(java.awt.event.KeyEvent evt) {

// TODO add your handling code here:

if (evt.getKeyCode() == evt.VK_ENTER)

enviarDatos();

}

/**

* El método principal invoca a que se ejecute la aplicación del cliente */

*/

public static void main(String args[]) {

java.awt.EventQueue.invokeLater(new Runnable() {

Override

public void run() {

new Aplicacion_Cliente().setVisible(true);

}

});

}

/* A continuación se presenta el método de abrirConexionConElServidor para estar

enviando los datos desde el cliente*/

public void abrirConexionConElServidor()

{

String msg = null;

String ip = null;

int puerto = 0;

try

{

//Establecemos la ip del servidor

ip = txtIp.getText().trim();

//Establecemos el puerto a través del cual se abrirá el socket.

puerto = Integer.valueOf(txtPuertoSocket.getText().trim());

//Establecemos la conexión con el servidor

cliente = new Socket(ip, puerto);

//Habilitamos y deshabilitamos controles de la interfaz de usuario

//para evitar un funcionamiento indeseado.

habilitarControlesAperturaDeSocket(false);

//Notificamos al usuario que se ha creado un socket.

msg ="Conexión realizada con el servidor exitosamente.";

JOptionPane.showMessageDialog(this, msg, "Socket creado.",

JOptionPane.INFORMATION_MESSAGE);

//Obtenemos los objetos para poder leer y escribir a través

//del socket

entrada = cliente.getInputStream();

Page 19: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

19

salida = cliente.getOutputStream();

lector = new DataInputStream(entrada);

escritor = new DataOutputStream(salida);

}

catch (NumberFormatException nfe)

{

//Notificamos al usuario que se ha creado un socket

msg = "El numero de puerto debe ser un numero entero mayor a 0 " +

"y menor a 65535.";

JOptionPane.showMessageDialog(this, msg,

"Numero de puerto incorrecto",

JOptionPane.ERROR_MESSAGE);

nfe.printStackTrace();

}

catch (Exception e)

{

//Si el usuario intenta acceder a un numero de puerto no disponible se captura el

error y se le notifica al usuario.

msg = "Error al intentar abrir socket.\n" +

"Ip: " + txtIp.getText() + "\n"+

"Puerto: " + puerto +

"\n\nProbablemente el puerto esté en uso o el firewall " +

"de su equipo o del servidor impidio su apertura.";

JOptionPane.showMessageDialog(this, msg, "Error",

JOptionPane.ERROR_MESSAGE);

}

}

// Se tiene el método para cerrar el socket previamente abierto.

public void cerrarSocket()

{

String msg = null;

try

{

leyendo = false;

if (cliente != null)

{

//Con esto se cierra la conexión con el servidor

cliente.close();

cliente = null;

habilitarControlesAperturaDeSocket(true);

}

}

catch (Exception e)

{

//Si el usuario intenta cerrar un socket no disponible se captura el error

y se le notifica al usuario.

msg = "Error al intentar cerrar el socket.\n\n" +

"El sistema se cerrara después de este cuadro de dialogo.";

JOptionPane.showMessageDialog(this, msg, "Error",

JOptionPane.ERROR_MESSAGE);

e.printStackTrace();

}

}

Page 20: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

20

/* El siguiente es el método para en caso de entablar comunicación se habiliten los

componentes gráficos o se deshabiliten según sea el estado de la conexión */

public void habilitarControlesAperturaDeSocket(boolean value)

{

//Habilitamos los controles para la apertura del socket

lblIp.setEnabled(value);

txtIp.setEnabled(value);

lblPuertoSocket.setEnabled(value);

txtPuertoSocket.setEnabled(value);

btnAbrirPuerto.setEnabled(value);

//Deshabilitamos los controles de recepcion de datos y cierre

btnCerrarPuerto.setEnabled(!value);

txtDatos.setEnabled(!value);

btnEnviarDatos.setEnabled(!value);

}

/*A continuación se presenta el método que envía datos, el cual primero los obtiene

de txtDatos y después los envía mediante un DataOutputStream */

public void enviarDatos()

{

try

{

escritor.writeUTF(txtDatos.getText());

}

catch (Exception e)

{

e.printStackTrace();

}

}

// Variables declaration - do not modify

private javax.swing.JButton btnAbrirPuerto;

private javax.swing.JButton btnCerrarPuerto;

private javax.swing.JButton btnEnviarDatos;

private javax.swing.JLabel lblIp;

private javax.swing.JLabel lblPuertoSocket;

private javax.swing.JTextField txtDatos;

private javax.swing.JTextField txtIp;

private javax.swing.JTextField txtPuertoSocket;

// End of variables declaration

//Objeto que se comunicará con el servidor para enviarle datos.

Socket cliente;

//Objetos que permitirán leer y escribir flujos de bits través del socket.

InputStream entrada;

OutputStream salida;

//Objetos que permitirán leer valores de algún tipo desde el socket.

DataInputStream lector;

DataOutputStream escritor;

//Esta variable sirve para mantener o cerrar el ciclo de lectura de datos

//desde el cliente

boolean leyendo;

}

Page 21: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

21

Autorreflexiones

Además de enviar tu trabajo de la Evidencia de aprendizaje, es importante que desarrolles

las preguntas que tu Docente en línea(a) presente, a partir de ellas, debes elaborar tu

Autorreflexión en un archivo de texto llamado DPO3_U3_ATR_XXYZ. Posteriormente envía

tu archivo mediante la herramienta Autorreflexiones.

Cierre de la unidad

Has concluido la tercera unidad de la asignatura. A lo largo de esta unidad revisaste los

principios del modelo de comunicaciones Cliente – Servidor, de esta misma manera

abordaste el tema de Streams, que como sabes se requieren para el intercambio de

información y, en esta unidad, pudiste utilizarlos para que ese intercambio de información se

realice entre diferentes computadoras. Por último, revisaste la manipulación de sockets para

realizar una conexión entre diferentes equipos que permita el intercambio de datos mediante

estos.

Al concluir esta unidad, concluyes también la materia Programación Orientada a Objetos III,

en ella te adentraste en conceptos avanzados de la programación, iniciaste en la unidad

uno con el manejo de archivos que te permitan almacenar información o extraerla, en la

unidad dos abordaste la programación paralela mediante threads y, por último, en esta

unidad generaste programas en red que intercambien información entre diferentes

computadoras. Con la aplicación de estos temas ampliarás la gama de desarrollos de

software en los que podrás participar.

Es aconsejable que revises nuevamente la unidad en caso de que los temas que se acaban

de mencionar no te sean familiares o no los recuerdes, de no ser este tu caso, ¡Felicidades!

concluiste con la asignatura Programación Orientada a Objetos III.

Para saber más…

Para que puedas ejecutar los programas que se te presentan, así como las actividades es

importante que instales un IDE en tu computadora, se recomienda NetBeans, puedes

descargarlo de forma gratuita de la siguiente liga: http://netbeans.org/downloads/

Es recomendable que pruebes los códigos que se presentan en los ejemplos que se

encuentran en cada fuente de consulta mencionada.

Page 22: Carrera: Desarrollo de software Semestre 05 · Carrera: Desarrollo de software Semestre 05 Programa de la asignatura: Programación orientada a objetos III Unidad 3. Programación

Programación orientada a objetos III Unidad 3. Programación en red

22

Fuentes de consulta

Abián, M. (2004) Java y las redes. [Documento en formato PDF]

Díaz, F. (2011) SOCKETS EN JAVA. [Documento en formato PDF]

FIC (2007). Laboratorio de Redes de Comunicaciones. España: Universidad de la

Coruña. Tomado de: http://quegrande.org/apuntes/EI/3/RC/practicas/08-

09/seminario_java.pdf

Hervás, C. (2004). Modelo de cliente-servidor en Java. España: Universidad de Cordoba.

Tomado de http://www.uco.es/~i22mugua/_private/aso_pdf/cliserjava.pdf

Martinez, P. (2000). Sockets en Java. España: Universidad de Alicante. Tomado de:

http://www.dlsi.ua.es/asignaturas/sid/JSockets.pdf

Niemeyer, P (2000). Learning Java. E. U.: O´Reilly.

Oracle (2012). The JAVA Tutorials. Estados Unidos de América: Oracle

Suarez, L. (2001) El paquete java.io. Javahispano. Disponible en:

http://www.javahispano.com

Universidad tecnológica nacional (2001). Conceptos básicos sobre Redes. Argentina:

Instituto Tecnológico de Buenos Aires. Recopilado en:

http://www.dednet.net/institucion/itba/cursos/000183/demo/biblioteca/121redesUTN.pdf