Receta para consumir servicio web SOAP de eBay en Java con NetBeans (por terminal)

5.1.09. Por ooscarr (ooscarr)

Netbeans

Consumir un servicio web en Java resultó más difícil de lo que pensaba. Por eso algunos servicios ofrecen SDKs para facilitar las cosas, pero aquí lo haremos a mano, consumiendo el Servicio Web SOAP que ofrece eBay desde el puro archivo WSDL (y la ayuda de NetBeans).

¿Por qué el SW de eBay? Bueno, uno, porque es uno de los pocos servicios web más famosos que ofrecen una API en SOAP (a todos les gustó REST).

De los grandes

Y dos, porque ni con Microsoft ni con Amazon pude lograr un resultado. Mi culpa. Así que sigamos con ebay.

De los más famosos que ofrecen sus servicios web por SOAP gratis, tenemos:

Ingredientes

Registro

Para obtener una clave para utilizar los servicios web de ebay, hay que registrarse en la página para desarolladores de ebay http://developer.ebay.com/.

Clave de desarrollador en eBay

Get more access keys

Después de registrarnos, pedimos unas claves Production keys que son como estas:

* Estas claves son inventadas. Consiga sus propias claves.
DEVID03abb543-5t3d-87k-na95f-o234bo854
AppID:UNAP3d995-2kj53-67u8-abcc-po988l9u035
CertID:4hd73h-9385-383d-as3j-ffie34u5eee35

WSDL

En esta ocasión vamos a utilizar la Shopping API. El archivo WSDL para el SOAP de eBay, se encuentra en la parte de Documentación y es éste:

http://developer.ebay.com/webservices/latest/ShoppingService.wsdl

Nuevo proyecto en Netbeans

Ahora, creamos un proyecto nuevo de tipo Aplicación Java

Nueva aplicación Java

Le puse de nombre SOAPebay.

Nombrando al proyecto SOAPebay en Netbeans 6.5
Terminar.

Después agregamos un Archivo nuevo de tipo Web Service Client

Nuevo archivo Web Services > Web Service Client.

Pegamos la dirección del WSDL http://developer.ebay.com/webservices/latest/ShoppingService.wsdl.

Specify the WSDL file of the Web Service
Terminar.

Y después que se genera el servicio web, arrastramos y soltamos el método FindItems desde Web Services References/ShoppingService/Shopping/Shopping al main del archivo Main.java del proyecto.

Arrastrar el método y soltar en el código Java en Netbeans.

Código

La cosa no es tan simple. Lo ideal hubiera sido que se generara todo automáticamente para llegar y reemplazar strings, pero por lo menos tenemos el esqueleto del código hecho.

Ahora que están todos los archivos internamente vinculados, reemplace todo el contenido de Main.java por esto:

package soapebay;

import javax.xml.ws.BindingProvider;

public class Main {

 //Cambiar APPID
 private static final String APPID = "UNAP3d995-2kj53-67u8-abcc-po988l9u035";
 private static final String CALLNAME = "FindItems";
 private static final String VERSION = "557";
 private static final String BASEURL="http://open.api.ebay.com/shopping?";

 private static BindingProvider bp;

 public static void main(String[] args) {
  
  String endpointURL = BASEURL+"callname=" + CALLNAME+"&version="+VERSION+"&appid=" + APPID;

  try {

   ebay.apis.eblbasecomponents.Shopping service = new ebay.apis.eblbasecomponents.Shopping();
   ebay.apis.eblbasecomponents.ShoppingInterface port = service.getShopping();bp = (BindingProvider) port;
   bp = (BindingProvider) port;
   bp.getRequestContext().
    put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
     endpointURL);
   // Inicializa los argumentos
   ebay.apis.eblbasecomponents.FindItemsRequestType findItemsRequest = new ebay.apis.eblbasecomponents.FindItemsRequestType();
   findItemsRequest.setQueryKeywords("iphone");
   // procesa los resultados
   ebay.apis.eblbasecomponents.FindItemsResponseType result = port.findItems(findItemsRequest);
   System.out.println ( " Consulta : " + endpointURL);
   System.out.println("Estado = "+result.getAck());
   System.out.println("Número total de Items= "+result.getTotalItems());
   System.out.println("URL = "+result.getItemSearchURL());

  } catch (Exception ex) {
   // TODO handle custom exceptions here
  }
 }
}

Y al presionar el botón Ejecutar (Run Main Project), en la consola o Panel de Salida debería aparecer lo siguiente:

compile:
run:
 Consulta : http://open.api.ebay.com/shopping?callname=FindItems&version=557&appid=UNAP3d995-2kj53-67u8-abcc-po988l9u035
Estado = SUCCESS
Número total de Items= 64525
URL = http://search.ebay.com/ws/search/SaleSearch?fsoo=1&fsop=1&satitle=iphone
GENERACIÓN CORRECTA (tiempo total: 59 segundos)

No olvidar cambiar la clave de la API en el código fuente. Y si se va a compilar por segunda vez, se debe limpiar (Clean) antes.

Looking forward

También intenté hacerlo por web, donde tiene más sentido el consumo de este servicio, pero al final no pude terminarlo debido a mi ignorancia en JavaBeans. Help.

Referencias

Etiquetas: , , ,

Consumir servicio web con Microsoft ASP.NET C# desde un WSDL

5.1.09. Por ooscarr (ooscarr)

Visual C#

Me pidieron que consumiera el servicio web que creé anteriormente en java pero con ASP.NET. Así que en este post mostraré cómo consumí el servicio web a partir del WSDL utilizando las herramientas oficiales de Microsoft® para Windows®.

Preparativos

Primero, obtenemos la ruta web al WSDL (en este caso, http://localhost:8080/Holaste/HolasteService?WSDL) y nos aseguramos que esté funcionando.

Nuevo sitio web

Después, abrir el Visual (en este caso, Microsoft® Visual Web Developer 2008 Express Edition, es gratis) y crear un Nuevo sitio web ASP.NET en Visual C#.

Nuevo sitio web C# en Microsoft Visual Web Developer 2008 Express Edition
Se creará un archivo Default.aspx.

Ahora vamos al menú Sitio web > Agregar referencia web..., y pegamos la dirección del WSDL.

Agregando WSDL en Microsoft Visual Web Developer 2008 Express Edition

Cuando aparezca el servicio, le ponemos un Nombre de referencia web, por ejemplo, localhost.

Poniendo nombre de referencia web al servicio en Microsoft Visual Web Developer 2008 Express Edition

De modo que quede en el Explorador de soluciones, más o menos así:

Captura de pantalla del Explorador de Soluciones del proyecto con el servicio web en App_WebREferences/localhost/HolasteService.discomap/

Código

El código, que pone un simple formulario y consume el servicio quedaría como sigue:

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<script runat="Server">
void Page_Load (object sender, EventArgs e) {
 
 // Crea el servicio
 localhost.HolasteService Servicio1 = new localhost.HolasteService();

    //Obtiene el nombre del formulario
    String nombre = Servicio1.diHola(CampoNombre.Text); 

 // Muestra el nombre, si obtiene alguno
    if (nombre == null || nombre == "Hola, ")
  Label1.Text = "[No se ingresó nombre]";
 else 
  Label1.Text = nombre;
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es-cl" lang="es-cl" dir="ltr">
<head>
 <title>Holaste</title>
 <meta http-equiv="content-type" content="application/xhtml+xml;charset=UTF-8" />
</head>
<body>
    <h1>Holaste</h1>
    <p>Este programa consume el servicio <a href="http://www.ooscarr.com/nerd/elblog/2008/12/crear-un-simple-servicio-web-en.php">Holaste</a>.</p>
    <h2>HolasteService</h2>
    <form id="form1" runat="server" method="post">
        <p><label for="CampoNombre">Nombre:</label>
            <asp:TextBox id="CampoNombre" runat="server"/></p>
        <p><button id="Submit" type="submit" runat="server">Enviar</button></p>
        
        <h3>Respuesta</h3>
        <p><strong style="text-decoration:blink;"><asp:Label id="Label1" runat="server"></asp:Label></strong></p>
    </form>
</body>
</html>

Rssultado

Finalmente lo ejecutamos, y debería aparecer algo parecido a esto:

ver referencia de resultado.
* La página es sólo de referencia. No sirve.

Artículos elacionados

Etiquetas: , , ,

Crear un simple servicio web SOAP en Java con NetBeans es re-fácil

21.12.08. Por ooscarr (ooscarr)

Netbeans

A través de un video tutorial (mencionado al final de este documento), aprendí a crear un simple servicio web con NetBeans.

Según leí, Sun removió el soporte para el WSDK (aunque igual se sigue distribuyendo) para reemplazarlo por GlassFish. Así que ni modo. Pero estas instrucciones también funcionan con Tomcat.

Crear nuevo proyecto

Lo primero es crear un nuevo proyecto, así que...

  1. Creamos un Nuevo proyecto, en mi caso de tipo Aplicación Web

    Captura de pantalla del asistente para crear un Nuevo proyecto en Netbeans

  2. Elijo un nombre para la aplicación web. Yo le llamé Holaste.

    Captura de pantalla del asistente para crear una Nueva Aplicación Web

  3. En los ajustes del servidor, elijo GlassFish o Tomcat, como siempre.

    Opción GlasshFish en los ajustes de servidor del asistente para crear nuevo Proyecto de Aplicación Web en NetBeans

  4. Y Terminar

    Asistente de Nuevo Proyecto de NettBeans creando el nuevo proyecto

¿Código?

Como toda apliación web, me aparece el típico index.jsp predeterminado en el que puedo aprovechar de describir el Servicio Web (puedo poner cualquier cosa, en realidad, porque esto no es parte del servicio web).

index.jsp

<%-- 
    Document   : index
    Created on : 21-dic-2008, 12:06:37
    Author     : ooscarr
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es-cl">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <title>Servicio web</title>
</head>
<body>
 <h1>Este es el Servicio web</h1>
 <p>Este servicio lo que hace es decir "Hola, [nombre]" a cambio
   de un parámetro [nombre] de tipo <code>String</code>.</p>
</body>
</html>

Creación del Servicio Web

Mmm... Bueno, en NetBeans es muy sencillo crear un Servicio Web, sólo basta seleccionar el nombre del proyecto (Holaste en mi caso) y poner Archivo Nuevo. Ahi también hay una opción llamada Web Service.

agregando un Nuevo archivo al proyecto con el asistente en NetBeans

Y le damos un nombre, por ejemplo, ServicioWeb.

Nombrando servicio web en NetBeans
Aproveché de agregarlo a un paquete llamado hola.

Añadir operaciones

Para añadir operaciones hay que sólo posicionarse sobre el Servicio Web y poner Add Operation...

Menú contextual para Servicio web en NetBeans

De otra forma, en el modo Design existe el botón Add Operation....

Botón Add Operation... en el modo Design del editor de servicios web de NetBeans.

Ahí le pongo un nombre, puedo añadir parámetros y elegir si lo quiero de tipo String, boolean, int, etc.

Añadiendo Operaciones a un Servicio web en NetBeans

ServicioWeb.java

Con eso se generará automáticamente el código esqueleto que puedo modificar para que me retorne "Hola, " + nombre;. Así:

package hola;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

/**
 *
 * @author ooscarr
 */
@WebService()
public class ServicioWeb {

 /**
  * Web service operation
  */
 @WebMethod(operationName = "diHola")
 public String diHola(@WebParam(name = "nombre")
 String nombre) {
  //TODO write your implementation code here:
  return "Hola, " + nombre;
 }

}

Probémoslo

Ya. Probémoslo. Para eso primero hay que armar el proyecto con el menú contextual del proyecto, opción Deploy.

GENERACIÓN CORRECTA (tiempo total: 7 segundos)

Y probar el servicio web, seleccionando el Servicio web, opción Test Web Service.

INFO: Dynamically creating request wrapper Class hola.jaxws.DiHola
INFO: Dynamically creating response wrapper bean Class hola.jaxws.DiHolaResponse
INFO: parsing WSDL...
INFO: generating code...
INFO: 
compiling code...
INFO: Invoking wsimport with http://localhost:8080/Holaste/ServicioWebService?WSDL
INFO: wsimport successful
INFO: parsing WSDL...
INFO: generating code...
INFO: 
compiling code...
INFO: Invoking wsimport with http://localhost:8080/Holaste/ServicioWebService?WSDL
INFO: wsimport successful

Si todo está bien instalado, se debería abrir una ventana del navegador más o menos así.

Página web, con formulario para probar las operaciones del Servicio Web, generada por NetBeans

Aquí, por ejemplo, si pongo Oscar en el formulario, se puede ver el código que entrega el servicio Web al cliente.

ver referencia.

WSDL

También es bueno hacer notar que NetBeans genera automáticamente el archivo WSDL (y su XML Schema también) para ser usado en las implementaciones de los Clientes.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.5-hudson-$BUILD_NUMBER-. -->
<definitions targetNamespace="http://hola/" name="ServicioWebService" xmlns:tns="http://hola/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<xsd:schema>
<xsd:import namespace="http://hola/" schemaLocation="ServicioWebService_schema1.xsd"/>
</xsd:schema>
</types>
<message name="diHola">
<part name="parameters" element="tns:diHola"/>
</message>
<message name="diHolaResponse">
<part name="parameters" element="tns:diHolaResponse"/>
</message>
<portType name="ServicioWeb">
<operation name="diHola">
<input message="tns:diHola"/>
<output message="tns:diHolaResponse"/>
</operation>
</portType>
<binding name="ServicioWebPortBinding" type="tns:ServicioWeb">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="diHola">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="ServicioWebService">
<port name="ServicioWebPort" binding="tns:ServicioWebPortBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL"/>
</port>
</service>
</definitions>

Fuente

Todo lo que dije lo saqué de un video hecho por un desarrollador de Sun. Lo puedes ver (en inglés) desde el siguiente link, por si te quedó alguna duda.

Etiquetas: ,

Agregar patrones a un elemento con atributos en un W3C XML Schema

26.11.08. Por ooscarr (ooscarr)

Llevo 3 días sufriendo pensando y probando todas las combinaciones posibles para agregar una restricción de patrón a un elemento con atributos. Finalmente di con la respuesta. Era mi primer XML Schema.

Explicar qué es y cómo se escribe un XML Schema da para largo y todavía no estoy muy seguro de algunos aspectos más avanzados, así que no lo voy a hacer (a menos que me sobre el tiempo).

Así que por lo que pude probar usando el excelente editor de XML Schema de netbeans (seguramente basado en algún validador de XML Schemas del W3C), sólo podía agregar restricciones a:

  • Elementos simples sin atributos
  • Elementos complejos con elementos hijos

Pero yo necesitaba agregar una restricción al contenido de un elemento con atributos a mi W3C XML Schema.

Problema

Digamos que tengo la siguiente etiqueta en mi XML:

<title type="text">A1</title>

...y necesito agregarle las siguientes restricciones de XML Schema:

<xsd:restriction base="xsd:string">
 <xsd:pattern value="[A-Z]+[0-9]+"/>
 <xsd:minLength value="2"/>
</xsd:restriction>

(Sí, se tratan de celdas de una planilla de cálculo)

Solución

Y la manera en que lo logré fue... ¡Ah! ¡Primero deja explicar que tenia un namespace llamado tns en la cabecera! (Poco relevante)

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 targetNamespace="http://www.ooscarr.com"
 xmlns:tns="http://www.ooscarr.com"
 elementFormDefault="qualified">

W3C XML Schema

Primero creé un tipo simple llamado ncelda

<xsd:simpleType name="ncelda">
 <xsd:restriction base="xsd:string">
  <xsd:pattern value="[A-Z]+[0-9]+"/>
 </xsd:restriction>
</xsd:simpleType>

Luego creé un tipo complejo llamado titulo basado en el ncelda

<xsd:complexType name="titulo">
 <xsd:simpleContent>
  <xsd:extension base="tns:ncelda">
   <xsd:attribute name="type" type="xsd:string"/>
  </xsd:extension>
 </xsd:simpleContent>
</xsd:complexType>

Y finalmente, agregué el elemento title de tipo titulo

<xsd:element name="title" type="tns:titulo"/>

Fin.

Con Netbeans

Netbeans

Para hacer lo mismo con la interfaz gráfica de netbeans; (de los 3: Source, Schema y Design) en el modo Schema, es cosa de

  1. agregar un Simple Type...
    Menú contextual Agregar un Simple Type...
  2. llamarlo ncelda
  3. con el método de derivación restriction
  4. usando la definición existente Built-in Types > string

Menú contextual Propiedades

Después ir a las propiedades del tipo creado y agregar al patrón (Pattern) la expresión regular

[A-Z]+[0-9]+

Y de ahí,

  1. Se crea el elemento complejo llamado titulo
  2. Lo personalizamos
    menú contextual, opción Personalizar
    y usamos la extensión existente ncelda
    Global Complex Type customizer
  3. Después creamos el elemento title usando el tipo existente titulo y le agregamos el atributo type
    menú contextual de agregar atributo

árbol del esquema en el modo Schema del editor de XML Schema de netbeans

0 Error(s),  0 Warning(s).

Etiquetas: ,

Ejemplo oficial de RMI en Java

18.11.08. Por ooscarr (ooscarr)

Se me pidió implementar un ejemplo de comunicación RMI en Java para un curso de Sistemas distribuidos. Y como estaba en inglés, traduzco el ejemplo que encontré en tutorial de introducción oficial de Java™ RMI. El famoso Hello, world

Los códigos

Lamentablemente, por la licencia, debo poner todos los comentarios iniciales correspondientes a los disclaimer, así que por eso se ven largos los códigos.

Hola.java

/*
 * Copyright 2004 Sun Microsystems, Inc. All  Rights Reserved.
 *  
 * Redistribution and use in source and binary forms, with or 
 * without modification, are permitted provided that the following 
 * conditions are met:
 * 
 * -Redistributions of source code must retain the above copyright  
 *  notice, this list of conditions and the following disclaimer.
 * 
 * -Redistribution in binary form must reproduce the above copyright 
 *  notice, this list of conditions and the following disclaimer in 
 *  the documentation and/or other materials provided with the 
 *  distribution.
 *  
 * Neither the name of Sun Microsystems, Inc. or the names of 
 * contributors may be used to endorse or promote products derived 
 * from this software without specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any
 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
 * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
 * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
 * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *  
 * You acknowledge that Software is not designed, licensed or 
 * intended for use in the design, construction, operation or 
 * maintenance of any nuclear facility.
 */
package ejemplo.hola;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Hola extends Remote {
    String diHola() throws RemoteException;
}

Servidor.java

/*
 * Copyright 2004 Sun Microsystems, Inc. All  Rights Reserved.
 *  
 * Redistribution and use in source and binary forms, with or 
 * without modification, are permitted provided that the following 
 * conditions are met:
 * 
 * -Redistributions of source code must retain the above copyright  
 *  notice, this list of conditions and the following disclaimer.
 * 
 * -Redistribution in binary form must reproduce the above copyright 
 *  notice, this list of conditions and the following disclaimer in 
 *  the documentation and/or other materials provided with the 
 *  distribution.
 *  
 * Neither the name of Sun Microsystems, Inc. or the names of 
 * contributors may be used to endorse or promote products derived 
 * from this software without specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any
 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
 * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
 * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
 * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *  
 * You acknowledge that Software is not designed, licensed or 
 * intended for use in the design, construction, operation or 
 * maintenance of any nuclear facility.
 */
package ejemplo.hola;

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Servidor implements Hola{

 public Servidor() {}

 public String diHola(){
  return "Hola, mundo";
 }

 public static void main(String args[]){

  try {
   Servidor obj = new Servidor();
   Hola stub = (Hola) UnicastRemoteObject.exportObject(obj, 0);

   // Liga los datos (stub) del objeto remoto en el registro
   Registry registro = LocateRegistry.getRegistry();
   registro.bind("Hola",stub);

   System.err.println("Servidor listo");
  } catch (Exception e) {
   System.err.println("Excepción del servidor: " + e.toString());
   e.printStackTrace();
  }
 }
}

Cliente.java

/*
 * Copyright 2004 Sun Microsystems, Inc. All  Rights Reserved.
 *  
 * Redistribution and use in source and binary forms, with or 
 * without modification, are permitted provided that the following 
 * conditions are met:
 * 
 * -Redistributions of source code must retain the above copyright  
 *  notice, this list of conditions and the following disclaimer.
 * 
 * -Redistribution in binary form must reproduce the above copyright 
 *  notice, this list of conditions and the following disclaimer in 
 *  the documentation and/or other materials provided with the 
 *  distribution.
 *  
 * Neither the name of Sun Microsystems, Inc. or the names of 
 * contributors may be used to endorse or promote products derived 
 * from this software without specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any
 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
 * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
 * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
 * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *  
 * You acknowledge that Software is not designed, licensed or 
 * intended for use in the design, construction, operation or 
 * maintenance of any nuclear facility.
 */
package ejemplo.hola;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Cliente {
 
 private Cliente() {}
 
 public static void main(String[] args){
  
  String host = (args.length < 1) ? null : args[0];
  try {
   Registry registro = LocateRegistry.getRegistry(host);
   Hola stub = (Hola) registro.lookup("Hola");
   String respuesta = stub.diHola();
   System.out.println("respuesta: " + respuesta);
  } catch (Exception e) {
   System.err.println("Exception del cliente: " + e.toString());
   e.printStackTrace();
  }
    }
}

Cómo compilarlo y ejecutarlo

Para compilarlo, sólo hay que ejecutar el comando usual:

javac -d clases Hola.java Servidor.java Cliente.java

El directorio donde se guardarán las clases (en este ejemplo llamado clases debe existir previamente.

El árbol con los archivos debería quedar como en la siguiente imagen:

Captura de pantalla del contenido de la carpeta del proyecto: 3 archivos .java más un subdirectorio ejemplo/hola/ con 3 archivos .class en él
Repito. La carpeta clases debe existir previamente.

Para ejecutar este ejemplo, se necesita hacer lo siguiente:

  • Iniciat el registro Java RMI
  • Iniciar el servidor
  • Ejecutar el cliente

Iniciar el registro Java RMI

Para iniciar el registro, ejecuta el comando rmiregistry en el host del servidor. Este comando no produce ningún mensaje de salida (cuando es satisfactorio) y típicamente corre en background. Para más informción, vea la documentación de las herramientas de rmiregistry [paraSolaris, Windows].

Por ejemplo, en Solaris™:

rmiregistry &

En OS X con Java 5 por lo menos es igual que en Solaris pero sin el &

rmiregistry

O, en la plataforma Windows:

start rmiregistry 

Por defecto, el registro corre en el puerto TCP 1099. Para iniciar un registro en un puerto diferente, especifica el número de puerto desde la línea de comandos. Por ejemplo, para iniciar el registro en el puerto 2001 sobre la plataforma Windows:

start rmiregistry 2001

Si el registro estará ejecutándose en un puerto distinto del 1099, necesitarás especificar el número de puerto en las llamadas a LocateRegistry.getRegistry en las clases Server y Client. Por ejemplo, si el registro está ejecutándose sobre el puerto 2001 en este ejemplo, la llamada a getRegistry en el servidor sería:

Registry registry = LocateRegistry.getRegistry(2001);

Iniciar el servidor

Para iniciar el servidor, ejecuta la clase Servidor usando el comando java siguiente:

En Solaris:

java -classpath clases -Djava.rmi.server.codebase=file:clases/ ejemplo.hola.Servidor &

En OS X:

java -classpath clases -Djava.rmi.server.codebase=file:clases/ ejemplo.hola.Servidor

Bajo la plataforma Windows:

start java -classpath clases -Djava.rmi.server.codebase=file:clases/ ejemplo.hola.Servidor

donde clases es el directorio raíz del árbol de archivos de las clases (el mismo clases de cuando fueron compilados los archivos fuentes). Definiendo la propiedad de sistema java.rmi.server.codebase asegura que el registro pueda cargar la definición de interfaz remota (ojo que el slash final es importante).

La salida del servidor debería verse como esto:

Servidor listo

El servidor mantiene ejecutándose hasta que el proceso es terminado por el usuario (típicamente matando al proceso).

Ejecutar el cliente

Una vez que el servidor está listo, el cliente puede ser ejecutado de la siguiente forma:

java -classpath clases ejemplo.hola.Cliente

donde clases es el directorio raíz del árbol de archivos de las clases (el mismo clases de cuando fueron compilados los archivos fuentes).

La salida del cliente es el siguiente mensaje:

respuesta: Hola, mundo

Referencias

Etiquetas: ,

3 Servidores 1 Cliente y 1 Coordinador por UDP con búfer en Java

15.11.08. Por ooscarr (ooscarr)

En esta entrega, se realiza lo del coordinador pero mediante buffer por el protocolo UDP.

Como ya se mencionó anteriormente, la única diferencia con el código anterior es que se ha introducido un servidor más entre el cliente y las operaciones como se muestra en la siguiente figura:

Cliente conectado a un Coordinador (5000) que se conecta a Raíz cuadrada (5001), logaritmo natural (5002) y potencia (5003)

El nuevo servidor Coordinador se comunicará con los demás por medio del puerto 5000, al igual como lo hacían los otros 3 servidores con el cliente anteriormente.

Códigos

Básicamente, lo que se hizo fue dividir el código Cliente.java del ejemplo anterior en 2:

Cliente.java
es el programa que se comunica con el usuario y proporciona la interfaz de comunicación con él.
Coordinador.java
que recibe los datos otorgados por Cliente.java, se comunica con el servidor correspondiente de cada operación para obtener el resultado y lo devuelve a Cliente.java para que se la muestre al usuario.

Cliente.java

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class Cliente{

 /** Creates a new instance of DataTimeClient */
 public Cliente() {
 }

 /* Se definen cuatro variables que leen DESDE EL TECLADO
  stdin1 para saber si sigue o no
  stdin2 para saber qué función desea realizar
  stdin3 para obtener el valor que quiere resolver
  stdin4 para el exponente, en caso que desea resolver una potencia*/
 private static BufferedReader stdin1 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin2 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin3 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin4 = new BufferedReader(new InputStreamReader(System.in));

 public static void main(String args[]) throws IOException{

  //La dirección del servidor de raíces cuadradas
  String IP_COORDINADOR= "localhost";
  //Puerto del servidor de raíces cuadradas
  int PUERTO_COORDINADOR=5000;

  //Por defecto sí sigue (empieza)
  String sigue="s";

  System.out.println("\nBuenos días");

  //Mientras el usuario siga con ganas de resolver
  while(sigue.equals("s")){
   // Menú
   System.out.println("\n¿Qué desea hacer?\n");
   System.out.println("1. Raíz cuadrada");
   System.out.println("2. Logaritmo natural");
   System.out.println("3. Potencia");
   System.out.println("\n4. Salir");
   System.out.print("\n- Ingrese su opcion: ");
   //Guardo opción en un string para evitar errores
   String opcion=stdin2.readLine();

   if(opcion.equals("1")){
    System.out.println("RAÍZ CUADRADA");
    try{

     //Lee el valor desde teclado
     System.out.print("Raíz cuadrada de: ");
     String valor=stdin3.readLine();

     //Envía el valor a la función de más abajo
     String resultado=realizar_operacion(IP_COORDINADOR,PUERTO_COORDINADOR,opcion,valor,null);

     //Imprime el resultado
     System.out.println("= "+resultado);

    } catch(Exception e){
     System.err.println(e);
    }

   }
   else if(opcion.equals("2")){
    System.out.println("LOGARITMO NATURAL");
    try{

     //Lee el valor desde teclado
     System.out.print("Logaritmo natural de: ");
     String valor=stdin3.readLine();

     //Envía el valor a la función de más abajo
     String resultado=realizar_operacion(IP_COORDINADOR,PUERTO_COORDINADOR,opcion,valor,null);

     //Imprime el resultado
     System.out.println("= "+resultado);

    } catch(Exception e){
     System.err.println(e);
    }

   }
   else if(opcion.equals("3")){
    System.out.println("POTENCIA");
    try{

     //Lee los valores desde teclado
     System.out.print("Base de la potencia: ");
     String base=stdin3.readLine();
     System.out.print("Exponente: ");
     String exponente=stdin4.readLine();

     //Envía el valor a la función de más abajo
     String resultado=realizar_operacion(IP_COORDINADOR,PUERTO_COORDINADOR,opcion,base,exponente);

     //Imprime el resultado
     System.out.println("= "+resultado);

    } catch(Exception e){
     System.err.println(e);
    }

   }
   else if(opcion.equals("4")){
    break;//Opción Salir
   }
   else{
    System.out.println("Se equivocó.");
    break;
   }

   //Sigue el ciclo
   System.out.print("\nDesea realizar otra operación? (s/n): ");
   sigue = stdin1.readLine();
  }
  System.out.println("Adios.");

 }



 /* Función realizar operacion se encarga de comunicarse con el coordinador*/
 static String realizar_operacion(String IP_COORDINADOR,int PUERTO_COORDINADOR,String opcion,String valor1,String valor2){

  //Se define el búfer
        byte[] buf = new byte[256];
  byte[] buf2 = new byte[256];

  DatagramSocket socket;

  String respuesta=null;

  try {
   //Nuevo socket UDP
   socket = new DatagramSocket();

   buf = opcion.getBytes();

   //Se crea el paquete
   DatagramPacket paquete = new DatagramPacket(buf,buf.length,InetAddress.getByName(IP_COORDINADOR),PUERTO_COORDINADOR);
   //Se envía el paquete por el socket
   socket.send(paquete);

   buf = new byte[256];
   buf = valor1.getBytes();
   paquete = new DatagramPacket(buf,buf.length,InetAddress.getByName(IP_COORDINADOR),PUERTO_COORDINADOR);
   socket.send(paquete);

   if(valor2!=null){
    buf = new byte[256];
    buf = valor2.getBytes();
    //Pongo el valor en el paquete de salida
    paquete = new DatagramPacket(buf,buf.length,InetAddress.getByName(IP_COORDINADOR),PUERTO_COORDINADOR);
    //Envío lo que hay en el canal de salida
    socket.send(paquete);
   }

   paquete = new DatagramPacket(buf2,buf2.length);
   //Se espera que llegue el paquete
   socket.receive(paquete);

   respuesta=new String(paquete.getData());
   //System.out.println(respuesta);

   socket.close();

  } catch (IOException ex) {
   ex.printStackTrace();
  }
  //Retorna el valor recibido como respuesta
  return respuesta;
 }
}

Coordinador.java

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class Coordinador {

 /** Creates a new instance of DataTimeClient */
 public Coordinador() {
 }

 public static void main(String args[]) {

  //Puerto que se abrirá en esta máquina para responder a los clientes
  int PUERTO_COORDINADOR=5000;

  //Variable que guarda el nombre del servidor de raíz cuadrada
  String IP_SQRT="localhost";// con =null; también funciona
  //Variable que guarda el puerto del servidor de raíz cuadrada
  int PUERTO_SQRT=5001;
  //Variable que guarda el nombre del servidor de logaritmo natural
  String IP_LN="localhost";
  //Variable que guarda el puerto del servidor de logaritmo natura
  int PUERTO_LN=5002;
  //Variable que guarda el nombre del servidor de potencias
  String IP_POTENCIA="localhost";
  //Variable que guarda el puerto del servidor de potencias
  int PUERTO_POTENCIA=5003;

  while (true){
   try{

    String valor1=null;
    String valor2=null;
    String respuesta=null;

    DatagramSocket socket = new DatagramSocket(PUERTO_COORDINADOR);

    byte[] buf = new byte[256];
    DatagramPacket paquete = new DatagramPacket(buf, buf.length);

    System.out.println("Esperando la conexion de cliente ...");

    socket.receive(paquete);
    String operacion=new String(paquete.getData(),0,paquete.getLength());

    InetAddress IP_CLIENTE = paquete.getAddress();
    int PUERTO_CLIENTE = paquete.getPort();

    paquete = new DatagramPacket(buf, buf.length);
    socket.receive(paquete);
    valor1=new String(paquete.getData(),0,paquete.getLength());    

    System.out.print("Operacion "+operacion+" es... ");

    if(operacion.equals("1")){
     //Si quiere raíz cuadrada
     System.out.println("raíz cuadrada.");
     //Envía el valor a la función de más abajo
     respuesta=realizar_operacion(IP_SQRT,PUERTO_SQRT,valor1,null);
     System.out.print("sqrt("+valor1+")");
    } else if(operacion.equals("2")){
     System.out.println("logaritmo natural.");
     //Si quiere logaritmo natural
     respuesta=realizar_operacion(IP_LN,PUERTO_LN,valor1,null);
     System.out.print("ln("+valor1+")");
    } else if(operacion.equals("3")){
     //Si quiere potencia
     System.out.println("potencia.");
     //Recibo el exponente desde el cliente
     System.out.println("Esperando exponente... ");
     paquete = new DatagramPacket(buf, buf.length);
     socket.receive(paquete);     
     valor2=new String(paquete.getData(),0,paquete.getLength());

     respuesta=realizar_operacion(IP_POTENCIA,PUERTO_POTENCIA,valor1,valor2);
     System.out.print(valor1+"^"+valor2);
    } else{
     System.out.println("otra desconocida.");
     respuesta="Error. No está definida la operación solicitada.";
    }

    //Imprime el resultado
    System.out.println(" = "+respuesta);

    System.out.print("Enviando respuesta... ");
    buf = new byte[256];
    buf = respuesta.getBytes();
    paquete = new DatagramPacket(buf, buf.length, IP_CLIENTE,PUERTO_CLIENTE);
    socket.send(paquete);
    System.out.println("OK");

    socket.close();

   } catch(Exception e){
    System.err.println(e);
   }
  }

 }



 /* Función realizar operacion se encarga de comunicarse con el coordinador*/
 static String realizar_operacion(String host,int puerto,String valor1,String valor2){

  //Se define el búfer
  byte[] buf = new byte[256];
  byte[] buf2 = new byte[256];

  String respuesta=null;

  try {
   //Nuevo socket UDP
   DatagramSocket sockete = new DatagramSocket();

   buf = valor1.getBytes();
   //Se crea el paquete
   DatagramPacket paquete = new DatagramPacket(buf,buf.length,InetAddress.getByName(host),puerto);
   //Se envía el paquete por el socket
   sockete.send(paquete);

   //Si llega un cuarto argumento (el exponente de la potencia)
   if(valor2!=null){
    buf = new byte[256];
    buf = valor2.getBytes();
    //Pongo el valor en el paquete de salida
    paquete = new DatagramPacket(buf,buf.length,InetAddress.getByName(host),puerto);
    //Envío lo que hay en el canal de salida
    sockete.send(paquete);
   }

   paquete = new DatagramPacket(buf2,buf2.length);
   //Se espera que llegue el paquete
   sockete.receive(paquete);

   respuesta=new String(paquete.getData());
   //System.out.println(respuesta);

   sockete.close();

  } catch (IOException ex) {
   ex.printStackTrace();
  }
  //Retorna el valor recibido como respuesta
  return respuesta;
 }
}

Sqrt.java

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class Sqrt{
 static DatagramSocket socket ;

 //Constructor crea nueva instancia del main
 public Sqrt() {
 }

 public static void main(String[] args) throws IOException{
  int PUERTO_SQRT=5001;

  while(true) {
   try{

    socket = new DatagramSocket(PUERTO_SQRT);

    byte[] buf = new byte[256];
    DatagramPacket paquete = new DatagramPacket(buf, buf.length);

    System.out.println("Esperando para resolver raíces cuadradas...");
    //Se recibe un paquete por el socket
    socket.receive(paquete);
    String valor=new String(paquete.getData(), 0, paquete.getLength());

    System.out.print("Raíz cuadrada de "+valor+" es... ");

    //Creo una instancia de las operaciones definidas
    Operaciones operar=new Operaciones(valor);

    //Realizo la operación
    String resultado=null;
    resultado=String.valueOf(operar.sqrt());
    System.out.println(resultado);

    System.out.print("Enviando resultado... ");
    buf = new byte[256];
    buf = resultado.getBytes();
    InetAddress IP_COORDINADOR = paquete.getAddress();
    int PUERTO_COORDINADOR = paquete.getPort();
    paquete = new DatagramPacket(buf, buf.length, IP_COORDINADOR,PUERTO_COORDINADOR);
    socket.send(paquete);

    System.out.println("OK");

    //Se cierra la petición de conexión llamada socket
    try{
     socket.close();
    }
    catch (Exception ex){
     System.err.println(ex);
    }

   } catch (Exception e){
    System.err.println("Hubo un error.");
    System.err.println(e);
    if(socket!=null){
     System.out.print("Cerrando socket ...");
     try{
      socket.close();
      System.out.println("OK");
     } catch (Exception ex){
      System.out.println("FAIL");
     }
    }
    break;
   }
  }//fin del while(true)
 }

}

Ln.java

es casi igual a Sqrt.java

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class Ln{
 static DatagramSocket socket ;
 
 //Constructor crea nueva instancia del main
 public Ln() {
 }
 
 public static void main(String[] args) throws IOException{
  int PUERTO_LN=5002;
  
  while(true) {
   try{

    socket = new DatagramSocket(PUERTO_LN);

    byte[] buf = new byte[256];
    DatagramPacket paquete = new DatagramPacket(buf, buf.length);

    System.out.println("Esperando para resolver logaritmos naturales..");
    //Se recibe un paquete por el socket
    socket.receive(paquete);
    String valor=new String(paquete.getData(), 0, paquete.getLength());

    System.out.print("Logaritmo natural de "+valor+" es... ");

    //Creo una instancia de las operaciones definidas
    Operaciones operar=new Operaciones(valor);

    //Realizo la operación
    String resultado=null;
    resultado=String.valueOf(operar.ln());
    System.out.println(resultado);

    System.out.print("Enviando resultado... ");
    buf = new byte[256];
    buf = resultado.getBytes();
    InetAddress IP_COORDINADOR = paquete.getAddress();
    int PUERTO_COORDINADOR = paquete.getPort();
    paquete = new DatagramPacket(buf, buf.length, IP_COORDINADOR,PUERTO_COORDINADOR);
    socket.send(paquete);

    System.out.println("OK");

    //Se cierra la petición de conexión llamada socket
    try{
     socket.close();
    }
    catch (Exception ex){
     System.err.println(ex);
    }

   } catch (Exception e){
    System.err.println("Hubo un error.");
    System.err.println(e);
    if(socket!=null){
     System.out.print("Cerrando socket ...");
     try{
      socket.close();
      System.out.println("OK");
     } catch (Exception ex){
      System.out.println("FAIL");
     }
    }
    break;
   }
  }//fin del while(true)
 }

}

Potencia.java

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class Potencia{
    static DatagramSocket socket ;
 
    //Constructor crea nueva instancia del main
    public Potencia() {
    }
    
    public static void main(String[] args) throws IOException{
  int PUERTO_POTENCIA=5003;

  while(true) {
   try{
    
    socket = new DatagramSocket(PUERTO_POTENCIA);

    byte[] buf = new byte[256];
    DatagramPacket paquete = new DatagramPacket(buf, buf.length);

                System.out.println("Esperando para resolver potencias...");
    //Se recibe un paquete por el socket
                socket.receive(paquete);
    String valor1=new String(paquete.getData(), 0, paquete.getLength());
    
                socket.receive(paquete);
    String valor2=new String(paquete.getData(), 0, paquete.getLength());
    
    System.out.print(valor1+" elevado a "+valor2+" es... ");
    
    //Creo una instancia de las operaciones definidas
    Operaciones operar=new Operaciones(valor1,valor2);
    
    //Realizo la operación
    String resultado=null;
    resultado=String.valueOf(operar.potencia());
    System.out.println(resultado);
    
    System.out.print("Enviando resultado... ");
    buf = new byte[256];
                buf = resultado.getBytes();
                InetAddress IP_COORDINADOR = paquete.getAddress();
                int PUERTO_COORDINADOR = paquete.getPort();
                paquete = new DatagramPacket(buf, buf.length, IP_COORDINADOR,PUERTO_COORDINADOR);
                socket.send(paquete);
    
    System.out.println("OK");
    
    //Se cierra la petición de conexión llamada socket
    try{
     socket.close();
    }
    catch (Exception ex){
     System.err.println(ex);
    }
    
   } catch (Exception e){
    System.err.println("Hubo un error.");
    System.err.println(e);
    if(socket!=null){
     System.out.print("Cerrando socket ...");
     try{
      socket.close();
      System.out.println("OK");
     } catch (Exception ex){
      System.out.println("FAIL");
     }
    }
    break;
   }
  }//fin del while(true)
    }
    
}

Etiquetas: ,

Cliente/Servidor por UDP con búfer en java

27.10.08. Por ooscarr (ooscarr)

No sólo por TCP/IP se pueden comunicar varios servidores, sino que también por UDP. En estos 2 ejemplos también se hará uso de búfer.

¿Qué es UDP?

User Datagram Protocol (UDP) es uno de los protocoles base del Conjunto de Protocolos de Internet. Por medio del UDP, programas en cmputadores conectados por red pueden enviar mensajes cortos a veces conocidos como datagramas (usando Datagram Sockets) de un lado al otro. UDP es a veces llamado el Protocolo Universal de Datagramas. El protocolo fue diseñado por David P. Reed en 1980 y formalmente definido en RFC 768.

UDP no garantiza la confiabilidad o el orden de la manera en que lo hace TCP. Los Datagramas pueden llegar en distinto orden, aparecer duplicados, o perderse sin informar. Al evitar el trabajo de revisar si cada paquete de verdad llegó hace a UDP más rápido y más eficiente, para aplicaciones que no necesitan envíos garantizados. Aplicaciones sensibles al tiempo a menudo usan UDP porque los paquetes recientemente enviados tienen preferencia a los paquetes atrasados. La naturaleza de la falta de estados de UDP también es útil para servidores que responden pequeñas consultas de un enorme número de clientes. A diferencia de TCP, UDP es compatible con broadcast de paquetes (enviando a todos en una red local) y multicasting (enviar a todos los suscritos).

Como aplicaciones de red comunes que utilizan UDP se incluyen: El Sistema de Nombres de Dominio (DNS), aplicaciones streaming media tales como IPTV, Voz sobre IP (VoIP), Trivial File Transfer Protocol (TFTP) y juegos online.

Seguir leyendo en Wikipedia

Ejemplo 1

Como primer ejemplo, encontré esta simple comunicación donde el Cliente le envía un paquete cualquiera al Servidor y éste le responde con la fecha y hora:

DataTimeClient.java

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class DataTimeClient {
    
    /** Creates a new instance of DataTimeClient */
    public DataTimeClient() {  
 }
    
    public static void main(String args[]) {
        byte[] buf = new byte[256];
        DatagramSocket socket;
        try {
            socket = new DatagramSocket();
            InetAddress address= InetAddress.getByName("localhost");
            DatagramPacket packet = new DatagramPacket(buf,buf.length,address,9090);
            socket.send(packet);
            packet = new DatagramPacket(buf,buf.length);
            socket.receive(packet);
            System.out.println(new String(packet.getData()));
        } catch (IOException ex) {
            ex.printStackTrace();
        }       
    }
}

TimeServer.java

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Date;
/**
 *
 * @author pcrao
 */
public class TimeServer{
    static DatagramSocket socket ;
    /** Creates a new instance of Main */
    public TimeServer() {
  
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            socket = new DatagramSocket(9090);
            byte[] buf = new byte[256];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            while(true) {
                System.out.println("Listening");
                socket.receive(packet);          
                
                String toClient=new Date().toString();
                buf = toClient.getBytes();
                InetAddress address = packet.getAddress();
                int port = packet.getPort();
                packet = new DatagramPacket(buf, buf.length, address, port);
                socket.send(packet);
            }
            
        } catch (SocketException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
}

Servidor de Raíz cuadrada

Y para terminar, el mismo ejemplo que hicimos antes por TCP/IP, pero por UDP con búfer.

Cliente.java

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class Cliente {
    
    /** Creates a new instance of DataTimeClient */
    public Cliente() {  
 }
 
    /* Se definen cuatro variables que leen DESDE EL TECLADO
  stdin1 para saber si sigue o no
  stdin2 para saber qué función desea realizar
  stdin3 para obtener el valor que quiere resolver
  stdin4 para el exponente, en caso que desea resolver una potencia*/
 private static BufferedReader stdin1 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin2 = new BufferedReader(new InputStreamReader(System.in));
 
    public static void main(String args[]) {
  
  //La dirección del servidor de raíces cuadradas
  String IP_SQRT= "localhost";
  //Puerto del servidor de raíces cuadradas
  int PUERTO_SQRT=5001;
        
  //Por defecto sí sigue (empieza)
  String sigue="s";
  
  System.out.println("\nBuenos días");
  
  //Mientras el usuario siga con ganas de resolver
  while(sigue.equals("s")){
   
   System.out.println("RAÍZ CUADRADA");
   try{
    
    //Lee el valor desde teclado
    System.out.print("Raíz cuadrada de: ");
    String valor=stdin2.readLine();
    
    //Envía el valor a la función de más abajo
    String resultado=realizar_operacion(IP_SQRT,PUERTO_SQRT,valor);
    
    //Imprime el resultado
    System.out.println("= "+resultado);
    
   } catch(Exception e){
    System.err.println(e);
   }   
   
   //Sigue el ciclo
   System.out.print("\nDesea realizar otra operación? (s/n): ");
   try{
    sigue = stdin1.readLine();
   } catch(Exception e){
    System.err.println(e);
   }
  }

    }



 /* Función realizar operacion se encarga de comunicarse con el coordinador*/
 static String realizar_operacion(String IP_SQRT,int PUERTO_SQRT,String valor){

  //Se define el búfer
        byte[] buf = new byte[256];
  byte[] buf2 = new byte[256];
  
        DatagramSocket socket;
  
  String respuesta=null;

  try {
   //Nuevo socket UDP
            socket = new DatagramSocket();

   buf = valor.getBytes();

   //Se crea el paquete
            DatagramPacket paquete = new DatagramPacket(buf,buf.length,InetAddress.getByName(IP_SQRT),PUERTO_SQRT);

   //Se envía el paquete por el socket
            socket.send(paquete);

            paquete = new DatagramPacket(buf2,buf2.length);
   //Se espera que llegue el paquete
            socket.receive(paquete);

   respuesta=new String(paquete.getData());
   //System.out.println(respuesta);
   
   socket.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
  //Retorna el valor recibido como respuesta
  return respuesta;
 }
}

Servidor.java

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class Servidor{
    static DatagramSocket socket ;
 
    //Constructor crea nueva instancia del main
    public Servidor() {
    }
    
    public static void main(String[] args) {
  int PUERTO_SQRT=5001;
  
  while(true) {
   try{
    
    socket = new DatagramSocket(PUERTO_SQRT);
    
    byte[] buf = new byte[256];
    DatagramPacket paquete = new DatagramPacket(buf, buf.length);
    
                System.out.println("Esperando para resolver raíces cuadradas...");
    //Se recibe un paquete por el socket
                socket.receive(paquete);
    String valor=new String(paquete.getData(), 0, paquete.getLength());
    
    System.out.print("Raíz cuadrada de "+valor+" es... ");
    
    //Creo una instancia de las operaciones definidas
    Operaciones operar=new Operaciones(valor);
    
    //Realizo la operación
    String resultado=null;
    resultado=String.valueOf(operar.sqrt());
    System.out.println(resultado);
    
    System.out.print("Enviando resultado... ");
    buf = new byte[256];
                buf = resultado.getBytes();
                InetAddress IP_CLIENTE = paquete.getAddress();
                int PUERTO_CLIENTE = paquete.getPort();
                paquete = new DatagramPacket(buf, buf.length, IP_CLIENTE,PUERTO_CLIENTE);
                socket.send(paquete);
    
    System.out.println("OK");
    
    //Se cierra la petición de conexión llamada socket
    try{
     socket.close();
    }
    catch (Exception ex){
     System.err.println(ex);
    }
    
   } catch (Exception e){
    System.err.println("Hubo un error.");
    System.err.println(e);
    if(socket!=null){
     System.out.print("Cerrando socket ...");
     try{
      socket.close();
      System.out.println("OK");
     } catch (Exception ex){
      System.out.println("FAIL");
     }
    }
    break;
   }
  }//fin del while(true)
    }
    
}

Fuentes

Artículos relacionados

Etiquetas: ,

3 Servidores 1 Cliente y 1 Coordinador con sockets por TCP/IP sin búfer en Java

26.10.08. Por ooscarr (ooscarr)

Siguiendo con esta serie de códigos java para la comunicación entre servidores, esta vez seguiré utilizando sockets pero ahora con la introducción de un quinto servidor que funcione como coordinador o proxy entre el cliente y los servidores encargados de las operaciones matemáticas.

Como dije, la única diferencia con el código anterior es que se ha introducido un servidor más entre el cliente y las operaciones como se muestra en la siguiente figura:

Cliente conectado a un Coordinador (5000) que se conecta a Raíz cuadrada (5001), logaritmo natural (5002) y potencia (5003)

El nuevo servidor Coordinador se comunicará con los demás por medio del puerto 5000, al igual como lo hacían los otros 3 servidores con el cliente anteriormente.

Códigos

Básicamente, lo que se hizo fue dividir el código Cliente.java del ejemplo anterior en 2:

Cliente.java
es el programa que se comunica con el usuario y proporciona la interfaz de comunicación con él.
Coordinador.java
que recibe los datos otorgados por Cliente.java, se comunica con el servidor correspondiente de cada operación para obtener el resultado y lo devuelve a Cliente.java para que se la muestre al usuario.

Los demás códigos:

...se mantienen igual.

Cliente.java

//Librería
import java.io.*;
import java.net.*;

public class Cliente{

 //Constructor
 public Cliente(){
 }
 
 /* Se definen cuatro variables que leen DESDE EL TECLADO
  stdin1 para saber si sigue o no
  stdin2 para saber qué función desea realizar
  stdin3 para obtener el valor que quiere resolver
  stdin4 para el exponente, en caso que desea resolver una potencia*/
 private static BufferedReader stdin1 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin2 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin3 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin4 = new BufferedReader(new InputStreamReader(System.in));
 
 //Función principal
 public static void main(String args[]) throws IOException{
  
  //Variable que guarda el nombre del servidor coordinador
  String IP_COORDINADOR="localhost";// con =null; también funciona
  //Variable que guarda el puerto del servidor cordinador
  int PUERTO_COORDINADOR=5000;
  
  //Por defecto sí sigue (empieza)
  String sigue="s";
  
  System.out.println("\nBuenos días");
  
  //Mientras el usuario siga con ganas de resolver
  while(sigue.equals("s")){
   // Menú
   System.out.println("\n¿Qué desea hacer?\n");
   System.out.println("1. Raíz cuadrada");
   System.out.println("2. Logaritmo natural");
   System.out.println("3. Potencia");
   System.out.println("\n4. Salir");
   System.out.print("\n- Ingrese su opcion: ");
   //Guardo opción en un string para evitar errores
   String opcion=stdin2.readLine();
   
   if(opcion.equals("1")){
    System.out.println("RAÍZ CUADRADA");
    try{
     
     //Lee el valor desde teclado
     System.out.print("Raíz cuadrada de: ");
     String valor=stdin3.readLine();
     
     //Envía el valor a la función de más abajo
     String resultado=realizar_operacion(IP_COORDINADOR,PUERTO_COORDINADOR,opcion,valor,null);
     
     //Imprime el resultado
     System.out.println("= "+resultado);

    } catch(Exception e){
     System.err.println(e);
    }
    
   }
   else if(opcion.equals("2")){
    System.out.println("LOGARITMO NATURAL");
    try{
     
     //Lee el valor desde teclado
     System.out.print("Logaritmo natural de: ");
     String valor=stdin3.readLine();
     
     //Envía el valor a la función de más abajo
     String resultado=realizar_operacion(IP_COORDINADOR,PUERTO_COORDINADOR,opcion,valor,null);
     
     //Imprime el resultado
     System.out.println("= "+resultado);
     
    } catch(Exception e){
     System.err.println(e);
    }

   }
   else if(opcion.equals("3")){
    System.out.println("POTENCIA");
    try{
     
     //Lee los valores desde teclado
     System.out.print("Base de la potencia: ");
     String base=stdin3.readLine();
     System.out.print("Exponente: ");
     String exponente=stdin4.readLine();
     
     //Envía el valor a la función de más abajo
     String resultado=realizar_operacion(IP_COORDINADOR,PUERTO_COORDINADOR,opcion,base,exponente);
     
     //Imprime el resultado
     System.out.println("= "+resultado);
     
    } catch(Exception e){
     System.err.println(e);
    }

   }
   else if(opcion.equals("4")){
    break;//Opción Salir
   }
   else{
    System.out.println("Se equivocó.");
    break;
   }
   
   //Sigue el ciclo
   System.out.print("\nDesea realizar otra operación? (s/n): ");
   sigue = stdin1.readLine();
  }
  
  System.out.println("Adios.");
 }
 
 
 /* Función realizar operacion se encarga de comunicarse con el coordinador*/
 static String realizar_operacion(String host,int puerto,String operacion,String valor1,String valor2){
  String respuesta=null;
  
  try {
   
   //System.out.print("Abriendo socket y creando flujos (streams)... ");
   Socket sockete = new Socket(host,puerto);
   //Creo dos canales de comunicación con la conexión
   DataOutputStream salida = new DataOutputStream(new BufferedOutputStream(sockete.getOutputStream()));
   DataInputStream entrada = new DataInputStream(new BufferedInputStream(sockete.getInputStream()));
   //System.out.println("OK\n");
   
   //Primero digo qué operación deseo realizar
   salida.writeUTF(operacion);
   //Envío lo que hay en el canal de salida
   salida.flush();
   
   //Pongo el valor en el canal de salida
   salida.writeUTF(valor1);
   //Envío lo que hay en el canal de salida
   salida.flush();

   //Si desea hacer una potencia
   if(operacion.equals("3")){
    //Pongo el segundo valor en el canal de salida
    salida.writeUTF(valor2);
    //Envío lo que hay en el canal de salida
    salida.flush();
   }
   
   //Leo lo recibido como respuesta por el canal de entrada
   respuesta = entrada.readUTF();
   //System.out.println("Resultado="+respuesta);

   //Se cierra la petición de conexión llamada sockete
   try{
    sockete.close();
   } catch (Exception ex){}
   
  }
  catch(Exception e){
   System.err.println(e);
  }
  //Retorna el valor recibido como respuesta
  return respuesta;
 }
 
}

Coordinador.java

//Librería
import java.io.*;
import java.net.*;

public class Coordinador{
 //Constructor
 public Coordinador(){
 }

 //Función principal
 public static void main(String args[]) throws IOException{
  
  //Puerto que se abrirá en esta máquina para responder a los clientes
  int PUERTO_COORDINADOR=5000;
  
  //Variable que guarda el nombre del servidor de raíz cuadrada
  String IP_SQRT="localhost";// con =null; también funciona
  //Variable que guarda el puerto del servidor de raíz cuadrada
  int PUERTO_SQRT=5001;
  //Variable que guarda el nombre del servidor de logaritmo natural
  String IP_LN="localhost";
  //Variable que guarda el puerto del servidor de logaritmo natura
  int PUERTO_LN=5002;
  //Variable que guarda el nombre del servidor de potencias
  String IP_POTENCIA="localhost";
  //Variable que guarda el puerto del servidor de potencias
  int PUERTO_POTENCIA=5003;

  ServerSocket serverSocket=null;
  Socket socket=null;

  try{
   serverSocket =new ServerSocket(PUERTO_COORDINADOR);
  } catch (Exception e){
   System.err.println("Error al crear socket");
   return;
  }
  
  while (true){
   try{
    String respuesta="";
    
    System.out.println("Esperando la conexion de cliente ...");
    //Acepto una petición de conexión
    socket=serverSocket.accept();
    //Creo dos canales de comunicación con la conexión
    DataOutputStream salida = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    DataInputStream entrada = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

    //Recibo opción desde el cliente
    String operacion = entrada.readUTF();
    System.out.println(operacion);
    System.out.print("Esperando valor 1... ");
    //Recibo el valor desde el cliente
    String valor1 = entrada.readUTF();
    System.out.println(valor1);
    
    if(operacion.equals("1")){
     //Si quiere raíz cuadrada
     respuesta=realizar_operacion(IP_SQRT,PUERTO_SQRT,valor1,null);
    } else if(operacion.equals("2")){
     //Si quiere logaritmo natural
     respuesta=realizar_operacion(IP_LN,PUERTO_LN,valor1,null);
    } else if(operacion.equals("3")){
     //Si quiere potencia
     System.out.print("Esperando valor 2... ");
     //Recibo el exponente desde el cliente
     String valor2 = entrada.readUTF();
     System.out.println(valor2);
     respuesta=realizar_operacion(IP_POTENCIA,PUERTO_POTENCIA,valor1,valor2);
    } else{
     salida.writeUTF("Error. No está definida la operación solicitada.");
    }
    
    System.out.print("Enviando respuesta ("+respuesta+")... ");
    //La pongo en el canal de salida
    salida.writeUTF(respuesta);
    //Se envía
    salida.flush();
    System.out.println("OK");
    
    //Se cierra la petición de conexión llamada socket
    try{
     socket.close();
    } catch (IOException ex){}
    
   }
   catch (Exception e){
    System.err.println("Cerrando la conexion del socket ...");
    if(socket!=null){
     try{
      socket.close();
     }
     catch (IOException ex){}
    }
   }
  }
  
 }
 
 
 /* Función realizar operacion se encarga de comunicarse con el servidor*/
 static String realizar_operacion(String host,int puerto,String valor1,String valor2){
  String respuesta=null;
  
  try {
   
   //System.out.print("Abriendo socket y creando flujos (streams)... ");
   Socket sockete = new Socket(host,puerto);
   //Creo dos canales de comunicación con la conexión
   DataOutputStream salida = new DataOutputStream(new BufferedOutputStream(sockete.getOutputStream()));
   DataInputStream entrada = new DataInputStream(new BufferedInputStream(sockete.getInputStream()));
   //System.out.println("OK\n");
   
   //Pongo el valor en el canal de salida
   salida.writeUTF(valor1);
   //Envío lo que hay en el canal de salida
   salida.flush();

   //Si llega un cuarto argumento (el exponente de la potencia)
   if(valor2!=null){
    //Pongo el valor en el canal de salida
    salida.writeUTF(valor2);
    //Envío lo que hay en el canal de salida
    salida.flush();
   }
   
   //Leo lo recibido como respuesta por el canal de entrada
   respuesta = entrada.readUTF();
   //System.out.println("Resultado="+respuesta);

   //Se cierra la petición de conexión llamada sockete
   try{
    sockete.close();
   } catch (Exception ex){}
   
  }
  catch(Exception e){
   System.err.println(e);
  }
  //Retorna el valor recibido como respuesta
  return respuesta;
 }
 
}

Etiquetas: ,

3 Servidores 1 Cliente con sockets en Java

25.10.08. Por ooscarr (ooscarr)

Con sockets, es fácil comunicar programas en java hasta con diferentes servidores.

Crearé un cliente que realiza las 3 operaciones: raíz cuadrada, logritmo natural y potencia; pero ahora distribuyéndolas en 3 servidores diferentes, uno para cada operación.

Un cliente se comunica con 3 servidores: Raíz cuadrada, logaritmo natural y potencia

Como, en mi caso, ejecutaré los 4 códigos en una misma máquina, he decidido asignarle a cada operación un puerto:

  • Puerto 5001 para la raíz cuadrada
  • Puerto 5002 para el logaritmo natural
  • Puerto 5003 para resolver las potencias

Códigos

La conexión mediante sockets ya la conocemos, así que vamos directamente a cómo quedan los códigos al distribuirlos.

Cliente.java

//Librería
import java.io.*;
import java.net.*;

public class Cliente{
 //Constructor
 public Cliente(){
 }
 
 /* Se definen cuatro variables que leen DESDE EL TECLADO
  stdin1 para saber si sigue o no
  stdin2 para saber qué función desea realizar
  stdin3 para obtener el valor que quiere resolver
  stdin4 para el exponente, en caso que desea resolver una potencia*/
 private static BufferedReader stdin1 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin2 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin3 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin4 = new BufferedReader(new InputStreamReader(System.in));
 
 //Función principal
 public static void main(String args[]) throws IOException{
  
  //Variable que guarda el nombre del servidor de raíz cuadrada
  String IP_SQRT="localhost";// con =null; también funciona
  //Variable que guarda el puerto del servidor de raíz cuadrada
  int PUERTO_SQRT=5001;
  //Variable que guarda el nombre del servidor de logaritmo natural
  String IP_LN="localhost";
  //Variable que guarda el puerto del servidor de logaritmo natura
  int PUERTO_LN=5002;
  //Variable que guarda el nombre del servidor de potencias
  String IP_POTENCIA="localhost";
  //Variable que guarda el puerto del servidor de potencias
  int PUERTO_POTENCIA=5003;
  
  //Por defecto sí sigue (empieza)
  String sigue="s";
  
  System.out.println("\nBuenos días");
  
  //Mientras el usuario siga con ganas de resolver
  while(sigue.equals("s")){
   // Menú
   System.out.println("\n¿Qué desea hacer?\n");
   System.out.println("1. Raíz cuadrada");
   System.out.println("2. Logaritmo natural");
   System.out.println("3. Potencia");
   System.out.println("\n4. Salir");
   System.out.print("\n- Ingrese su opcion: ");
   //Guardo opción en un string para evitar errores
   String opcion=stdin2.readLine();
   
   if(opcion.equals("1")){
    System.out.println("RAÍZ CUADRADA");
    try{
     
     //Lee el valor desde teclado
     System.out.print("Raíz cuadrada de: ");
     String valor=stdin3.readLine();
     
     //Envía el valor a la función de más abajo
     String resultado=realizar_operacion(IP_SQRT,PUERTO_SQRT,valor,null);
     
     //Imprime el resultado
     System.out.println("= "+resultado);

    } catch(Exception e){
     System.err.println(e);
    }
    
   }
   else if(opcion.equals("2")){
    System.out.println("LOGARITMO NATURAL");
    try{
     
     //Lee el valor desde teclado
     System.out.print("Logaritmo natural de: ");
     String valor=stdin3.readLine();
     
     //Envía el valor a la función de más abajo
     String resultado=realizar_operacion(IP_LN,PUERTO_LN,valor,null);
     
     //Imprime el resultado
     System.out.println("= "+resultado);
     
    } catch(Exception e){
     System.err.println(e);
    }

   }
   else if(opcion.equals("3")){
    System.out.println("POTENCIA");
    try{
     
     //Lee los valores desde teclado
     System.out.print("Base de la potencia: ");
     String base=stdin3.readLine();
     System.out.print("Exponente: ");
     String exponente=stdin4.readLine();
     
     //Envía el valor a la función de más abajo
     String resultado=realizar_operacion(IP_POTENCIA,PUERTO_POTENCIA,base,exponente);
     
     //Imprime el resultado
     System.out.println("= "+resultado);
     
    } catch(Exception e){
     System.err.println(e);
    }

   }
   else if(opcion.equals("4")){
    break;//Opción Salir
   }
   else{
    System.out.println("Se equivocó.");
    break;
   }
   
   //Sigue el ciclo
   System.out.print("\nDesea realizar otra operación? (s/n): ");
   sigue = stdin1.readLine();
  }
  
  System.out.println("Adios.");
 }
 
 
 /* Función realizar operacion se encarga de comunicarse con el servidor*/
 static String realizar_operacion(String host,int puerto,String valor1,String valor2){
  String respuesta=null;
  
  try {
   
   //System.out.print("Abriendo socket y creando flujos (streams)... ");
   Socket sockete = new Socket(host,puerto);
   //Creo dos canales de comunicación con la conexión
   DataOutputStream salida = new DataOutputStream(new BufferedOutputStream(sockete.getOutputStream()));
   DataInputStream entrada = new DataInputStream(new BufferedInputStream(sockete.getInputStream()));
   //System.out.println("OK\n");
   
   //Pongo el valor en el canal de salida
   salida.writeUTF(valor1);
   //Envío lo que hay en el canal de salida
   salida.flush();

   //Si llega un cuarto argumento (el exponente de la potencia)
   if(valor2!=null){
    //Pongo el valor en el canal de salida
    salida.writeUTF(valor2);
    //Envío lo que hay en el canal de salida
    salida.flush();
   }
   
   //Leo lo recibido como respuesta por el canal de entrada
   respuesta = entrada.readUTF();
   //System.out.println("Resultado="+respuesta);

   //Se cierra la petición de conexión llamada sockete
   try{
    sockete.close();
   } catch (Exception ex){}
   
  }
  catch(Exception e){
   System.err.println(e);
  }
  //Retorna el valor recibido como respuesta
  return respuesta;
 }
 
}

Sqrt.java

//
//  Sqrt.java
//  
/* Esta clase
 1. Abre un puerto
 2. Acepta una conexión
 3. Recibe un String
 4. Envía la raíz cuadrada del String
 5. Cierra la conexión
*/
//
//  Created by Oscar on 16-10-08.
//

import java.io.*;
import java.net.*;

public class Sqrt{
 //Constructor
 public Sqrt(){
 }
 
 public static void main (String[] args){
  //Puerto que se abrirá en esta máquina para responder a los clientes
  int PUERTO_SQRT=5001;
  
  Socket socket=null;
  ServerSocket serverSocket=null;
  
  try{
   serverSocket =new ServerSocket(PUERTO_SQRT);
  }
  catch (Exception e){
   System.err.println("Error al crear socket");
   return;
  }
  //Mientras el programa esté funcionando
  while (true){
   try{
    System.out.println("Esperando para resolver raíces cuadradas ...");
    //Acepto una petición de conexión
    socket=serverSocket.accept();
    
    //Creo dos canales de comunicación con la conexión
    DataOutputStream salida = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    DataInputStream entrada = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
    
    //System.out.print("Esperando valor... ");
    
    //Recibo el valor desde el cliente
    String valor = entrada.readUTF();
    
    //Creo el objeto con las operaciones definidas
    Operaciones operar=new Operaciones(valor);
    
    System.out.print("Raíz cuadrada de "+valor+" es... ");
    //Realizo la operación
    String resultado=String.valueOf(operar.sqrt());
    System.out.println(resultado);
    
    //La pongo en el canal de salida
    salida.writeUTF(resultado);
    System.out.print("Enviando respuesta... ");
    //Se envía
    salida.flush();
    System.out.println("OK");
    
    //Se cierra la petición de conexión llamada socket
    try{
     socket.close();
    }
    catch (IOException ex){}
   }
   catch (Exception e){
    System.err.println("Cerrando la conexion del socket ...");
    if(socket!=null){
     try{
      socket.close();
     }
     catch (IOException ex){}
    }
   }
  }
 }
}

Ln.java

//
//  Ln.java
//  
/* Esta clase
 1. Abre un puerto
 2. Acepta una conexión
 3. Recibe un String
 4. Envía el logaritmo natural del String
 5. Cierra la conexión
*/
//
//  Created by Oscar on 16-10-08.
//

import java.io.*;
import java.net.*;

public class Ln{
 //Constructor
 public Ln(){
 }
 
 public static void main (String[] args){
  //Puerto que se abrirá en esta máquina para responder a los clientes
  int PUERTO_LN=5002;
  
  Socket socket=null;
  ServerSocket serverSocket=null;
  
  try{
   serverSocket =new ServerSocket(PUERTO_LN);
  }
  catch (Exception e){
   System.err.println("Error al crear socket");
   return;
  }
  //Mientras el programa esté funcionando
  while (true){
   try{
    System.out.println("Esperando para resolver logaritmos naturales...");
    //Acepto una petición de conexión
    socket=serverSocket.accept();
    
    //Creo dos canales de comunicación con la conexión
    DataOutputStream salida = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    DataInputStream entrada = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
    
    //System.out.print("Esperando valor... ");
    
    //Recibo el valor desde el cliente
    String valor = entrada.readUTF();
    
    //Creo el objeto con las operaciones definidas
    Operaciones operar=new Operaciones(valor);
    
    System.out.print("ln("+valor+") = ");
    //Realizo la operación
    String resultado=String.valueOf(operar.ln());
    System.out.println(resultado);
    
    //La pongo en el canal de salida
    salida.writeUTF(resultado);
    System.out.print("Enviando respuesta... ");
    //Se envía
    salida.flush();
    System.out.println("OK");
    
    //Se cierra la petición de conexión llamada socket
    try{
     socket.close();
    }
    catch (IOException ex){}
   }
   catch (Exception e){
    System.err.println("Cerrando la conexion del socket ...");
    if(socket!=null){
     try{
      socket.close();
     }
     catch (IOException ex){}
    }
   }
  }
 }
}

Potencia.java

//
//  Potencia.java
//  
/* Esta clase
 1. Abre un puerto
 2. Acepta una conexión
 3. Recibe dos Strings
 4. Envía el valor del primer String
    elevado a la potencia del segundo String.
 5. Cierra la conexión
*/
//
//  Created by Oscar on 16-10-08.
//

import java.io.*;
import java.net.*;

public class Potencia{
 //Constructor
 public Potencia(){
 }
 
 public static void main (String[] args){
  //Puerto que se abrirá en esta máquina para responder a los clientes
  int PUERTO_POTENCIA=5003;
  
  Socket socket=null;
  ServerSocket serverSocket=null;
  
  try{
   serverSocket =new ServerSocket(PUERTO_POTENCIA);
  }
  catch (Exception e){
   System.err.println("Error al crear socket");
   return;
  }
  //Mientras el programa esté funcionando
  while (true){
   try{
    System.out.println("Esperando para resolver potencias...");
    //Acepto una petición de conexión
    socket=serverSocket.accept();
    
    //Creo dos canales de comunicación con la conexión
    DataOutputStream salida = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    DataInputStream entrada = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
    
    //System.out.print("Esperando valor... ");
    
    //Recibo el valor1 desde el cliente
    String valor1 = entrada.readUTF();
    //Recibo el valor2 desde el cliente
    String valor2 = entrada.readUTF();
    
    //Creo el objeto con las operaciones definidas
    Operaciones operar=new Operaciones(valor1,valor2);
    
    System.out.print(valor1+"^"+valor2+" = ");
    //Realizo la operación
    String resultado=String.valueOf(operar.potencia());
    System.out.println(resultado);
    
    //La pongo en el canal de salida
    salida.writeUTF(resultado);
    System.out.print("Enviando respuesta... ");
    //Se envía
    salida.flush();
    System.out.println("OK");
    
    //Se cierra la petición de conexión llamada socket
    try{
     socket.close();
    }
    catch (IOException ex){}
   }
   catch (Exception e){
    System.err.println("Cerrando la conexion del socket ...");
    if(socket!=null){
     try{
      socket.close();
     }
     catch (IOException ex){}
    }
   }
  }
 }
}

Etiquetas: ,

Cliente/Servidor mediante sockets sin búfer por TCP/IP en Java

25.10.08. Por ooscarr (ooscarr)

Comunicar 2 computadores por socket es más o menos simple en java.

Ejemplo 1

En la U nos dieron este ejemplo con sockets para que los trabajáramos.

Cliente.java

import java.io.*;
import java.net.*;

class Cliente {
 
 static final String HOST = "localhost";
 static final int PUERTO=5000;
 
 public Cliente() {
  try{
   
   Socket skCliente = new Socket( HOST , PUERTO );
   
   InputStream aux = skCliente.getInputStream();
   
   DataInputStream flujo = new DataInputStream( aux );
   
   System.out.println( flujo.readUTF() );
   
   skCliente.close();
   
  } catch( Exception e ) {
   
   System.out.println( e.getMessage() );
  }
 }
 
 public static void main( String[] arg ) {
  new Cliente();
 }
}

Servidor.java

import java.io.* ;
import java.net.* ;

class Servidor {
 static final int PUERTO=5000;
 
 public Servidor() {
  
  try {
   
   ServerSocket skServidor = new ServerSocket( PUERTO );

   System.out.println("Escucho el puerto " + PUERTO );
   
   for ( int numCli = 0; numCli < 3; numCli++) {
    Socket skCliente = skServidor.accept(); // Crea objeto
    System.out.println("Sirvo al cliente " + numCli);
    OutputStream aux = skCliente.getOutputStream();
    DataOutputStream flujo= new DataOutputStream( aux );
 
    flujo.writeUTF( "Hola cliente " + numCli );

    skCliente.close();
   }
   
   System.out.println("Demasiados clientes por hoy");

  } catch( Exception e ) {
   System.out.println( e.getMessage() );
  }
 }
 
 public static void main( String[] arg ) {
  new Servidor();
 }
}

Calculadora científica

Combinando el ejemplo anterior y el código de las funciones en la clase Operaciones de un artículo anterior, queda lo siguiente:

Cliente.java

//Librerías
import java.io.*;
import java.net.*;

public class Cliente{
 //Constructor
 public Cliente(){
 }
 
 /* Se definen dos variables que leen DESDE EL TECLADO
  stdin1 para saber si sigue o no
  stdin2 para obtener el valor que quiere resolver */
 private static BufferedReader stdin1 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin2 = new BufferedReader(new InputStreamReader(System.in));
 
 //Función principal
 public static void main(String args[]) throws IOException{
  
  //Variable que guarda el nombre del servidor de raíz cuadrada
  String IP_SQRT="localhost";// con =null; también funciona
  //Variable que guarda el puerto del servidor de raíz cuadrada
  int PUERTO_SQRT=5001;
  
  //Por defecto sí sigue (empieza)
  String sigue="s";
  
  System.out.println("\nBuenos días");
  
  //Mientras el usuario siga con ganas de resolver
  while(sigue.equals("s")){
  
   try{
    
    System.out.println("RAÍZ CUADRADA");
    
    //Lee el valor desde teclado
    System.out.print("Raíz cuadrada de: ");
    String valor=stdin2.readLine();
    
    //Envía el valor a la función de más abajo
    String resultado=realizar_operacion(IP_SQRT,PUERTO_SQRT,valor);
    
    //Imprime el resultado
    System.out.println("= "+resultado);
    
   } catch(Exception e){
    System.err.println(e);
   }

   //Sigue el ciclo
   System.out.print("\nDesea realizar otra operación? (s/n): ");
   sigue = stdin1.readLine();

  }

  System.out.println("Adios.");
 }


/* Función realizar operacion se encarga de comunicarse con el servidor*/
 static String realizar_operacion(String host,int puerto,String valor){
  String respuesta=null;
  
  try {
   
   //System.out.print("Abriendo socket y creando flujos (streams)... ");
   Socket sockete = new Socket(host,puerto);
   //Creo dos canales de comunicación con la conexión
   DataOutputStream salida = new DataOutputStream(new BufferedOutputStream(sockete.getOutputStream()));
   DataInputStream entrada = new DataInputStream(new BufferedInputStream(sockete.getInputStream()));
   //System.out.println("OK\n");
   
   //Pongo el valor en el canal de salida
   salida.writeUTF(valor);
   //Envío lo que hay en el canal de salida
   salida.flush();
   //Leo lo recibido como respuesta por el canal de entrada
   respuesta = entrada.readUTF();
   //System.out.println("Resultado="+respuesta);
   
   //Se cierra la petición de conexión llamada sockete
   try{
    sockete.close();
   } catch (Exception ex){}
   
  }
  catch(Exception e){
   System.err.println(e);
  }
  //Retorna el valor recibido como respuesta
  return respuesta;
 }

}

Servidor.java

//
//  Servidor.java
//  
/* Esta clase
 1. Abre un puerto
 2. Acepta una conexión
 3. Recibe un String
 4. Envía la raíz cuadrada del String
 5. Cierra la conexión
*/

import java.io.*;
import java.net.*;

public class Servidor{
 //Constructor
 public Servidor(){
 }
 
 public static void main (String[] args){
  //Puerto que se abrirá en esta máquina para responder a los clientes
  int PUERTO_SQRT=5001;
  
  Socket socket=null;
  ServerSocket serverSocket=null;
  
  try{
   serverSocket =new ServerSocket(PUERTO_SQRT);
  }
  catch (Exception e){
   System.err.println("Error al crear socket");
   return;
  }
  //Mientras el programa esté funcionando
  while (true){
   try{
    System.out.println("Esperando para resolver raíces cuadradas ...");
    //Acepto una petición de conexión
    socket=serverSocket.accept();
    
    //Creo dos canales de comunicación con la conexión
    DataOutputStream salida = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    DataInputStream entrada = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
    
    System.out.println("Bienvenido");
    //System.out.print("Esperando valor... ");
    
    //Recibo el valor desde el cliente
    String valor = entrada.readUTF();
    
    //Creo el objeto con las operaciones definidas
    Operaciones operar=new Operaciones(valor);
    
    System.out.print("Raíz cuadrada de "+valor+" es... ");
    //Realizo la operación
    String resultado=String.valueOf(operar.sqrt());
    System.out.println(resultado);
    
    //La pongo en el canal de salida
    salida.writeUTF(resultado);
    System.out.print("Enviando respuesta... ");
    //Se envía
    salida.flush();
    System.out.println("OK");
    
    //Se cierra la petición de conexión llamada socket
    try{
     socket.close();
    }
    catch (IOException ex){}
   }
   catch (Exception e){
    System.err.println("Cerrando la conexion del socket ...");
    if(socket!=null){
     try{
      socket.close();
     }
     catch (IOException ex){}
    }
   }
  }
 }
}

Pronto más.

Referencias

Etiquetas: ,

Ejemplo de polimorfismo en java (creo)

20.10.08. Por ooscarr (ooscarr)

Voy a crear una clase Java con funciones que reciben 1 o 2 parámetros y retornan el resultado de una de las operaciones: Potencia, Raíz Cuadrada y Logaritmo Natural.

Operaciones.java

Marco con negrita el polimorfismo

/**
 * Estas funciones reciben un string con un número
   y retornan el resultado en formato numérico
 */
public class Operaciones {
 int x;
 int y;

 //Si llegan 2 variables
    public Operaciones(String x, String y) {
     this.x = Integer.valueOf(x).intValue();
     this.y = Integer.valueOf(y).intValue();
    }
 //Polimorfismo 1 variable
    public Operaciones(String x) {
     this.x = Integer.valueOf(x).intValue();
    }
 //Raíz cuadrada (SQuare RooT)
    double sqrt() {
     double resultado=0;
     resultado=(double)Math.sqrt(x);
     return(resultado);
    }
 //Logaritmo Natural
    double ln() {
     double resultado=0;
     resultado=(double)Math.log(x);
     return(resultado);
    }
 //Potencia
    double potencia() {
     double resultado=0;
     resultado=(double)Math.pow(x,y);
     return(resultado);
    }
}

Cliente.java

Y un ejemplo de programa que haga uso de estas funciones, sería:

import java.io.*;

public class Cliente{
 
 private static BufferedReader stdin1 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin2 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin3 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin4 = new BufferedReader(new InputStreamReader(System.in));
 
 public static void main(String args[]) throws IOException{
  
  Cliente a = new Cliente();
  
  String sigue="s";
  
  System.out.println("\nBuenos días");
  
  try{
   while(sigue.equals("s")){
    System.out.println("\n¿Qué desea hacer?\n");
    System.out.println("1. Raíz cuadrada");
    System.out.println("2. Logaritmo natural");
    System.out.println("3. Potencia");
    System.out.println("\n");
    System.out.println("4. Salir");
    System.out.print("\n- Ingrese su opcion: ");
    String opcion=stdin1.readLine();
    
    if(opcion.equals("1")){
     System.out.println("RAÍZ CUADRADA");
     System.out.print("Raíz cuadrada de: ");
     String valor1=stdin2.readLine();
     
     Operaciones operar=new Operaciones(valor1);
     String resultado=String.valueOf(operar.sqrt());
     
     System.out.println("= "+resultado);
    }
    else if(opcion.equals("2")){
     System.out.println("LOGARITMO NATURAL");
     System.out.print("ln de: ");
     String valor1=stdin2.readLine();
     
     Operaciones operar=new Operaciones(valor1);
     String resultado=String.valueOf(operar.ln());
     
     System.out.println("= "+resultado);
    }
    else if(opcion.equals("3")){
     System.out.println("POTENCIA");
     System.out.print("Base: ");
     String valor1=stdin2.readLine();
     System.out.print("Exponente: ");
     String valor2=stdin3.readLine();
     
     Operaciones operar=new Operaciones(valor1,valor2);
     String resultado=String.valueOf(operar.potencia());
     
     System.out.println("= "+resultado);
    }
    else if(opcion.equals("4")){
     break;
    }
    else{
     System.out.println("Se equivocó.");
     break;
    }
    
    System.out.print("\nDesea realizar otra operación? (s/n): ");
    sigue = stdin4.readLine();
   }
  } catch(Exception e){
   System.err.println(e);
  }
  
  System.out.println("Adios.");
 }
}

Compilación

Luego de compilarlos con

javac Operaciones.java
javac Cliente.java

Y ejecutarlo con

java Cliente

Resulta algo así

Buenos días

¿Qué desea hacer?

1. Raíz cuadrada
2. Logaritmo natural
3. Potencia


4. Salir

- Ingrese su opcion: 3
POTENCIA
Base: 2
Exponente: 3
= 8.0

¿Desea realizar otra operación? (s/n): n
Adios.

Etiquetas: ,

Publicidad