Documentazione Contatti      
Documentazione > Tutorial > Introduzione a jrpc
Hide
Best Practices
EJB
Frameworks
Howto
J2EE
J2ME and Wireless
J2SE
JSP e Servlet
Java Application Server
Java IDE/Tools
Java Media
Java Security
Java Sys Admin
Java e XML
Java e SQL
OpenSource Java
Patterns
Repository
Tesi
UML
Web Services
Slide
White Paper di jws.it
project management
Eventi
Groovy



Online le slide del Javaday IV


Blaise Pascal
È molto più bello sapere qualcosa di tutto, che tutto di una cosa


XSD e XMLbeans



  Visualizza Commenti (0) Aggiungi Commento    
 
Introduzione a jrpc
By Luca Stancapiano
10 giugno 2005

  Introduzione a jrpc
Program Costruzione di un Client con Distinct ONC RPC/XDR per Java
Program Creazione del Server RPC in java
Program Creazione del Server RPC in C

Questo tutorial permette di costruire una piccola applicazione che mostra tutte le funzionalità di distinct jrpc. Distinct Jrpc è un prodotto certificato da Sun Microsystems. E' a pagamento e si puo' trovare su www.distinct.com. Esso introduce il java nel protocollo RPC (remote procedure calling). RPC è un protocollo di comunicazione Client-Server utilizzato per il prelievo e lo spostamento di dati da una macchina all'altra. RPC lavora con il protocollo intermedio XDR (eXternal Data Representation) che permette di specificare dettagliamente la struttura dei messaggi che vengono scambiati durante l'esecuzione di una chiamata di procedura remota. Il Distinct ONC RPC/XDR Toolkit for Java è un insieme di tools e librerie che permettono di scrivere applicazioni client/server completamente in java su protocollo RPC/XDR.

Il jrpc permette di:

  • far comunicare un client java con un server ONC RPC/XDR.
  • essere utilizzato da un'applicazione java esistente senza doverla riscrivere. E' sufficiente creare un modulo XDR per ogni classe dell'applicazione rappresentante un dato di entrata o di uscita e estenderlo in esse.
  • creare un'applicazione client/server completamente o parzialmente in java. Vedremo in seguito la semplicità con cui è possibile collegare classi java con codici scritti in c

E' formato da:

  • Il compilatore Jrpcgen che traduce l'interfaccia standard RPC/XDR in sorgenti java che implementano gli stubs client server. In pratica esegue una traduzione di un file IDL con estensione .x (scritto nel formato XDR) in java
  • Il Distinct ONC RPC/XDR per Java che contiene le librerie run time ONC RPC/XDR conformi al RFC 1831 (RPC: Remote Procedure Call Protocol Specification Version 2) e RFC 1832 (XDR: External Data Representation Standard). L'API e' formata da classi che vi permettono di scrivere client in Java, per server RPC, che possono essere inseriti in applets e quindi essere eseguiti da un comune browser Web. Vi permette anche di sviluppare server indipendenti ONC RPC in java. Il pacchetto permette collegamenti su TCP e UDP ..
  • Un'applicazione in java che implementa l'rpcbind. Si occupa di fornire le porte di comunicazione per il collegamento tra client e server. ..
  • L'utility RPCInfo mostra una lista che i servizi registrano con l'RPCBIND su un sistema. Questa utility può essere utilizzata per interrogare l' rpcbind o i portmapper sull'host locale (specificando "localhost") locale o su un host remoto (specificando il nome dell'host come un argomento di riga comandi).
  • Il RPCGw CGI script che permette l'esecuzione di RPCs su Internet dove i firewalls bloccano tutti i protocolli che non utilizzano porte fisse, come RPC. Con RPCGw potete anche chiamare server RPC (da un Java applet) che non sono situati sullo stesso host come il server web ma altrove nella vostra LAN. Per preservare l'integrità e la privacy della vostra LAN, RPCGw utilizza una lista di controlli accessi sofisticata che vi permette di specificare esattamente quale procedura RPC utilizza ..

In questa prima parte descriviamo:

  • guida sulla costruzione del client rpc in java e la creazione di un'interfaccia XDR.
  • guida sulla costruzione di un server RPC in java.
  • guida sulla costruzione di un server RPC in C utilizzabile con il client java. Con JRPC e' anche possibile collegare allo stesso modo un client c con un server java.

La guida è divisa in tre parti,ovvero la creazione di un client, la creazione di un server nella prima parte e nella seconda parte vari approfondimenti sul ONC RPC/XDR Toolkit tra cui l'utilizzo dei firewalls.



Costruzione di un Client con Distinct ONC RPC/XDR per Java top
Questa parte riguarda la costruzione di un client RPC in java. Creeremo un'applicazione che puo' essere usata sia come stand-alone che come applet nel caso lo volessimo lanciare da un browser.

 

Quando si inizia un'applicazione ONC RPC, la prima cosa da fare è scrivere un'interfaccia XDR. Rappresenta i dati di ingresso che verranno passati al server,il dato di uscita (un servizio rpc puo' mandare un'unico dato per volta al client). Distinct ONC RPC/XDR for Java comprende il linguaggio XDR descritto nel RFC 1832 (XDR: External Data Representation Standard). Per convenzione i files XDR hanno l'estensione .x.

1.1. Il file XDR

Il codice qui sotto riportato è un IDL (interface definition language) che chiamero' progetto.x. E' un semplice servizio che preleva delle linee da un testo. Da notare il forte utilizzo da parte di XDR della sintassi C.

%/****************************************
%* prova progetto.x *
%****************************************/

 struct request {
     int from;
     int to;
     };

 struct result {
    int number;
    string line;
    struct result *next;
    };

 typedef result *res_list;

  program PROGETTO_SERVER {
          version PROGETTO_VERSION {
                   res_list get_line(request) = 1;
          } = 1;
   } = 0x20000023;


E' diviso in 5 parti:

  1. Commento che inizia con '%'.
  2. La struct request di input. 
  3. La struct response di output.
  4. Il typedef res_list corrispondente al result. Il typedef è richiesto necessariamente da XDR affinchè possa tornare un puntatore a Result ..E' infatti non ammessa la dichiarazione di questo tipo : Result *get_line(request) = 1; .Se proprio non si vuole usare un typedef si potrebbe dichiarare il servizio in quest'altro modo: Result get_line(request) = 1; Ovviamente l'implementazione del codice risulterà abbastanza diversa dall'esempio della guida. Lo stesso discorso vale per la request. 
  5. Il progetto PROGETTO_SERVER.

1.2 Il Client java

Una volta creato il IDL è sufficiente compilare con Jrpcgen. Il pacchetto Jrpcgen creerà in automatico tutte le classi necessarie per trasformare il nostro codice in un Client RPC.Nel caso di progetto.x, se la sintassi è corretta verranno create le seguenti classi:

>>java Jrpcgen progetto.x
Jrpcgen V4.0, Copyright 1997 - 2001 by Distinct Corporation
progetto.x :

writing: request.java
writing: result.java
writing: res_list.java
writing: progetto.java

Si tratta di quattro classi, che implementano il client stub collegato al servizio progetto: le prime tre classi rappresentano i dati di input e output e implementano la classe XDRType, la quale contiene le informazioni relative alla conversione dei dati XDR a java; la quarta classe è chiamata stub ed è la descrizione del progetto vero e proprio che contiene la descrizione del servizio get_line. Essa implementa la classe JRPCClient.

1.2.1 Lo Stub JRPC

Diamo un occhiata ora allo stub progetto.java.

/* **************************************
* Stub JRPC *
****************************************/

import com.distinct.rpc.*;
import java.io.IOException;
import java.net.InetAddress;

/**
*This class was automatically generated by Jrpcgen from the RPC/XDR file "progetto.x" <br>.
* It defines the client interface to a server implementing the "progetto" interface.
*/

public class progetto extends JRPCClient {

/** Program ID of the interface. */
    public static final int PROGETTO_SERVER = 0x20000023;

/**
* Creates and connects an RPC client for a server that implements the "PartecipazioniRilevanti" interface.
* Calls the remote Portmapper in order to get the port of the server.
* @param host The host on which the server lives.
* @param stream true for a TCP connection, false for UDP.
* @exception RPCError When the calls fails for any reason.
*/
    public static final int PROGETTO_VERSION = 1;

/**
* Creates and connects an RPC client for a server that implements the "progetto" interface.
* Calls the remote Portmapper in order to get the server.port
* @param host The host on which the server resides.
* @param stream true for a TCP connection, false for UDP.
* @exception RPCError When the calls fail for any reason.
*/

   public progetto(InetAddress host, boolean stream) throws RPCError {
              super(host, PROGETTO_SERVER, PROGETTO_VERSION, stream);
     }

/**
* Creates and connects an RPC client for a server that implements the "progetto" interface.
* The client is connected to a server with a known port. (No interaction with a portmapper)
* @param host The host on which the server resides.
* @param port The port on which the server listens.
* @param stream True for a TCP connection, false for UDP.
* @exception RPCError When the calls fail for any reason.
*/

   public progetto(InetAddress host, int port, boolean stream) throws RPCError {
              super(host, PROGETTO_SERVER, PROGETTO_VERSION, port, stream);
     }

/**
* Creates an RPC client for a server that implements the "progetto" interface.
* It initializes it with an externally created protocol client object.
* @param protocol The protocol object that implements the client connection.
*/

    public progetto(ClientGeneric protocol) {
              super(protocol);
      }

    public static final int get_line = 1;

/**
* Stub method that invokes the server function "get_line" (version 1).
*/

     public res_list get_line_1(request arg) throws RPCError, IOException {
             res_list retval = new res_list();
             GetClient().Call(get_line, arg, retval);
             return retval;
        }
 };

L'istanza di questa classe manda la chiamata al server. Utilizza il servizio di portmapper per trovare la porta della connessione. Senza entrare in tutti i dettagli possiamo vedere facilmente che questa classe è formata da diverse costanti, tre costruttori e un metodo pubblico get_line_1 () che ha lo stesso nome di get_line () nel file XDR. Potete anche vedere che le linee dall'inizio del file XDR (le tre righe di commento) sono state copiate sulla sorgente Java generata, senza i caratteri iniziali del %. In questo modo Jrpcgen genera commenti che possono essere utilizzati dallo strumento di documentazione javadoc automatico. nbsp;

Come tutte le classi principali client-stub, la classe estende JRPCClient. Questa classe fornisce la struttura per server chiamanti RPC utilizzando i protocolli più diversi possibili. Simili alla rilegatura C di ONC RPC, le costanti sono il numero e la versione delle prestazioni così come un numero ordinale per ogni procedura. Dei tre costruttori il primo (public progetto (InetAddress host, boolean stream ) throws RPCError) è probabilmente il piu' utilizzato. Lo utilizzeremo nella nostra applicazione client. Infine, il metodo get_line_1 () è quello che dobbiamo invocare quando vogliamo interagire con il server. L' estensione _1 deriva dal fatto che questa è la realizzazione della versione 1 di questo programma RPC. ..

1.2.2 I file di definizione delle variabili

Analizziamo anche una delle tre classi risultato,il result.java:

/****************************************
* Distinct ONC RPC/XDR for Java Example *
****************************************/

import com.distinct.rpc.*;


public class result implements XDRType {
public int number;
public String line;
public result next;

/**
* Encodes an object of class result in compliance to RFC 1832 (XDR).
* @param xdrs The XDR output stream.
*/

  public void xdr_encode(XDRStream xdrs) {

     xdrs.xdr_encode_int(number);
     xdrs.xdr_encode_string(line);
     xdrs.xdr_encode_boolean(next != null);
     if (next != null)
     next.xdr_encode(xdrs);
     return;
  }

/**
* Decodes an object of class result in compliance to RFC 1832 (XDR).
* @param xdrs The XDR input stream.
* @exception RPCError When the call fails for any reason.
*/

  public void xdr_decode(XDRStream xdrs) throws RPCError {

      number = xdrs.xdr_decode_int();
      line = xdrs.xdr_decode_string();
      next = null;
      if (xdrs.xdr_decode_boolean()) {
             next = new result();
             next.xdr_decode(xdrs);
      }
      return;
   }
};

I commenti che vediamo qui sopra sono generati in automatico.Possiamo vedere in che modo la struct result viene trasformata in una classe java tramite xdr.Grazie ai metodi dell'XDRStream xdr_encode_int.xdr_encode_string e xdr_encode_boolean vengono tradotte le variabili c rispettivamente di tipo int,char * e boolean.

La classe è formata da due metodi xdr_encode e xdr_decode che rappresentano le azioni di codifica e decodifica. Da notare la trasformazione della lista result in un'applicazione java ricorsiva.nbsp;

1.2.3 L'applicazione Client

Ecco il primo passaggio per collegarsi a un server RPC. Non è importante sapere in che tipo di linguaggio è stato scritto il server per poter creare questi tipi di applicazioni.Grazie all'interfaccia XDR rimane tutto trasparente al programmatore.

import java.net.*;

public class applicazioneClient {
     static public void main(String[] args) {
            progetto client; // richiama il nostro progetto.java creato da JRPCgen
            request req = new request();
              try {
                client = new progetto(
                InetAddress.getByName(args[0]), // qui va l'indirizzo o il nome del server
                true); // viene messo a true se si vuole usare il TCP. A false per l'UDP

                for (int i = 0; i < 8; i++) {
                      for (int j = i + 1; j < 8; j++) {
                          req.from = i;
                          req.to = j;
                          System.out.println("from " + i + " to " + j);

                          res_list rl = client.get_line_1(req);
                          result res = rl.value;
                                while (res != null) {
                                       System.out.println(res.number+":"+res.line);
                                       res = res.next;
                                  }
                     }
                     client.CloseClient();
                  }
                  catch (Exception e) {
                  System.out.println(e.getMessage());
                  }
                 ...   
      }
}

Esaminiamola in dettaglio:

Prima di tutto importiamo java.net.* per prendere l'InetAddress del Server.
Non includiamo lo stub perchè consideriamo il tutto come un unico package.
Poi creiamo una semplice classe applicazioneClient con uno static main(). il main chiede in input un unica stringa con il nome del Server da specificare.
Dichiariamo il nostro "progetto". Sarà progetto a occuparsi della connessione con il Server.
Apriamo un Exception Context. Di solito, nel caso di JRPC, il Context è utilizzato per gli IOException e JRPCException. .. Con le System.out.println che ho messo sul codice possiamo stampare il risultato dell'appicazione Client.
Ora, possiamo eseguire la connessione con un semplice richiamo del costruttore "progetto". I parametri di ingresso sono il nome del server e un booleano che dice il tipo di protocollo: true per il TCP e false per l'UDP.
Se non viene lanciata alcuna Exception allora vuol dire che siamo connessi.
Una volta lanciata la connessione, possiamo iniziare a invocare la richiesta e prelevare i risultati. Istanziamo l'oggetto req, invochiamo il Server con res_list rl = client.get_line_1(req); e preleviamo i dati con l'oggetto res. Alla fine liberiamo la memoria e chiudiamo la connessione con client.CloseClient();.

Se la compilazione è andata a buon fine il risultato dell'appicazione sarà questo:

>java progetto localhost

from 0 to 1
0:prima riga di testo
from 0 to 2
0:prima riga di testo
1:seconda riga di testo
from 0 to 3
0:prima riga di testo
1:seconda riga di testo
2:terza riga di testo
from 0 to 4
0:prima riga di testo
1:seconda riga di testo
2:terza riga di testo
3:quarta riga di testo
from 0 to 5
....

Se invece compare questo:

>java progetto localhost

Server not available.

vuol dire che il server non è attivo.

1.2.4 Applicazione Client con le Applets

In linea di massima, potete utilizzare l'ONC RPC/XDR per classi e stubs Java generati da Jrpcgen dentro un applet come descritto sopra. Ma osservate che per default tutti i browsers Java-enabled non permettono collegamenti di rete a hosts diversi da quelli da dove viene caricata l'applet. Per poterlo fare , magari per la necessità di accedere alle risorse del client oppure per collegarsi a sua volta su un database situato in un altro pc, bisogna prendere degli accorgimenti.
Le soluzioni sono due: o si fa uso di certificati digitali, e da cio' parte un discorso molto vasto per via della diversità dei vari browsers, oppure configurando il JRPCgen nel classpath del browser della macchina che apre la connessione RPC.
Se entrambi i metodi non sono attuabili per la vostra applicazione oppure dovete collegarvi a un server RPC che è protetto da un firewall ,è possibile utilizzare sempre il protocollo HTTP utilizzando dei canali particolari.I particolari li vedremo nella seconda parte del tutorial. Con questa caratteristica univoca dell'ONC RPC/XDR si possono utilizzare facilmente piu' server in cascata. Pero' ci potrebbbero essere cali di prestazioni rispetto al collegamento diretto descritto prima ..



Creazione del Server RPC in java top

2.1 Il Server java

Ora vediamo come costruire il Server. Si riparte dal nostro progetto.x creato in precedenza e si ricompila con il JRPCgen aggiungendo un -S. In questo modo viene detto al JRPCgen che si sta compilando un Server:

>java Jrpcgen -S progetto.x

Jrpcgen V4.0, Copyright 1997 - 2001 by Distinct Corporation
progetto.x
writing: request.java
writing: result.java
writing: res_list.java
writing: progetto.java
writing: progettoServer.java

Anch'esso crea quattro classi come per il client (anche se stavolta non abbiamo bisogno di progetto.java perchè è utilizato solo dal client) con in piu' lo stub chiamato progettoServer.java.

1.2 Lo stub principale

Quindi ora esamineremo progettoServer.java.

/* **************************************
* Distinct ONC RPC/XDR for Java Example *
****************************************/

import com.distinct.rpc.*;

/**
* <b>PROGETTO_SERVER Server Stub</b>
* This class was automatically generated by Jrpcgen from the RPC/XDR file "progetto.x".<br>
* progetto: was interface PROGETTO_SERVER
*/

abstract public class progettoServer extends JRPCServer {

/** Interface Program */
       public static final int PROGETTO_SERVER = 0x20000023;

/** Interface Version */
       public static final int PROGETTO_VERSION = 1;

       public static final int get_line = 1;

/**
* Constructor that creates the RPC server that implements the "progetto" interface.
* @exception RPCError When the calls fail for any reason.
*/

      public progettoServer() throws RPCError {
             super(PROGETTO_SERVER, PROGETTO_VERSION, true);
             UnregisterServer();
             RegisterServer(StartUDP(0), false);
             RegisterServer(StartTCP(0), true);
      }

/**
* Constructor that creates the RPC server that implements the "progetto" interface at a fixed port.
* @param port The port on which the server listens.
* @exception RPCError When the calls fails for any reason.
*/

      public progettoServer(int port) throws RPCError {
              super(PROGETTO_SERVER, PROGETTO_VERSION, true);
              UnregisterServer();
              RegisterServer(StartUDP(port), false);
              RegisterServer(StartTCP(port), true);
      }

/**
* Dispatcher Routine that interprets the call requests.
* @param proc The index of the requested function.
* @param xin read the input parameter from this XDR stream.
* @param xout write the return parameter to this XDR stream.
* @return true, if the function with the index proc can be served, false otherwise.
*/

       synchronized public boolean DoCall(int proc, XDRStream xin, XDRStream xout) {
            try {
               switch (proc) {
                 case 0: {
                       return true;
                  }

                 case get_line: {
                       request arg = new request();
                       arg.xdr_decode(xin);
                       res_list ret = get_line_1(arg);
                       ret.xdr_encode(xout);
                        return true;
                 }

               default:
               return false;
             }
           }
           catch (Exception e) {
              return false;
           }
       }

/*
* Overwrite these abstract server methods for implementing the server's functionality.
*/

       abstract public res_list get_line_1(request arg);
         };

Questa classe STUB progettoServer rappresenta la struttura per un server che realizza l'interfaccia PROGETTO_SERVER descritta in progetto.x. Simile allo stub client, questa classe è formata da alcune costanti, due costruttori e un metodo finale get_line_1 () che ha lo stesso nome di get_line () del file XDR. Potete anche vedere che le righe dicommento all'inizio del file XDR sono state copiate sul sorgente Java generato senza i caratteri iniziali %.

progettoServer estende la classe di base JRPCServer. Questa classe rappresenta la struttura per la realizzazione di server RPC e permette di utilizzare un vasto numero di protocolli. ..Le costanti usate sono l'id del Server,il numero di versione del server e i numeri in ordine crescente dei servizi che esso contiene. Il metodo DoCall() è il nucleo del Server. Nel doCall viene specificato il numero del servizio da interrogare. Nel caso nostro ci si puo' riferire solo al numero 1 visto che abbiamo implementato un unico servizio (get_line) Alla fine, viene chiamato il metodo astratto get_line_1() che riempie l'oggetto res_list del risultato desiderato. Il metodo DoCall(),come tutti gli altri metodi,puo' essere richiamato da piu' server contemporaneamente.

2.3 L'applicazione Server

Ora siamo pronti a scrivere un server rpc in java. Vediamo lo stub che JRPC ciha creato:

import com.distinct.rpc.*;

public class MioServer extends progettoServer {

         static String text[] = {
                     "prima riga di testo",
                     "seconda riga di testo",
                     "terza riga di testo",
                     "quarta riga di testo",
                     "quinta riga di testo",
                     "sesta riga di testo",
                     "settima riga di testo",
                     "ottava riga di testo"
          };

      static public void main(String[] args) {
             try {
                 new MioServer ();
             }
             catch (RPCError e) {
             System.out.println(e.getMessage());
             }
      }

       public MioServer() throws RPCError {
             super();
       }

       // here we override and implement the real remote procedure
       public res_list get_line_1(request arg) {
             res_list rl = new res_list();
             result n = new result();

             for (int c = arg.from; c < arg.to; c++) {
            // allocate the next element in the list
                   n.next = new result();
                   n = n.next;
                   if (c == arg.from)
                         rl.value = n;

           // assign the line number
                    n.number = c;

          // assign the line (string)
                    n.line = text[c];
            }
            return rl;
     }
}

Abbiamo creato una classe MioServer derivante da progettoServer e finalmente troviamo l'implementazione di get_line_1(). Rispetto al server in C ci sono due differenze:

il metodo main() non viene definito dallo stub ma dalla classe che lo implementa. L'unica cosa che fa il main(), è quello di istanziare l'oggetto MioServer e catturare le Exception.
Rispetto alla versione in C la gestione della memoria in get_line_1() è inesistente.



Creazione del Server RPC in C top
3.1 Il Server C

E' molto utile vedere anche qualcosa scritto in C per poter vedere in pieno il funzionamento di JRPC.Come dicevamo, siccome l'XDR fa da tramite con il client e il server, è possibile che client e server comunichino anche con linguaggi diversi. Di norma un comune compilatore RPC utilizza una sintassi diquesto tipo: rpcgen progetto.x .Ora vediamo brevemente come lavora un server in C.

Dal file IDL vengono creati quattro sorgenti:

  1. progetto.h
  2. progetto_svc.c
  3. progetto_clnt.c
  4. progetto_xdr.c

3.2 L'header principale

L'header principale corrisponde è progetto.h e contiene tutte le informazioni sulle variabili e strutture utilizzate.

/*
* Please do not edit this file.
* It was generated using rpcgen.
*/

#ifndef _PROGETTO_H_RPCGEN
#define _PROGETTO_H_RPCGEN

#include
#ifndef _KERNEL
#include
#include
#endif /* !_KERNEL */

#ifdef __cplusplus
extern "C" {
          #endif


          struct request {
                     int from;
                     int to;
           };
           typedef struct request request;

           struct result {
                     int number;
                     char *line;
                     struct result *next;
           };
           typedef struct result result;

           typedef result *res_list;

          #define PROGETTO_SERVER 0x20000023
          #define PROGETTO_VERSION 1

          #if defined(__STDC__) || defined(__cplusplus)
          #define get_line 1
            extern enum clnt_stat get_line_1(request , res_list *, CLIENT *);
            extern bool_t get_line_1_svc(request , res_list *, struct svc_req *);
            extern int progetto_server_1_freeresult(SVCXPRT *, xdrproc_t, caddr_t);

          #else /* K&R C */
          #define get_line 1
           extern enum clnt_stat get_line_1();
           extern bool_t get_line_1_svc();
           extern int progetto_server_1_freeresult();
          #endif /* K&R C */

          /* the xdr functions */

           #if defined(__STDC__) || defined(__cplusplus)
           extern bool_t xdr_request(XDR *, request*);
           extern bool_t xdr_result(XDR *, result*);
           extern bool_t xdr_res_list(XDR *, res_list*);

           #else /* K&R C */
            extern bool_t xdr_request();
            extern bool_t xdr_result();
            extern bool_t xdr_res_list();

           #endif /* K&R C */

            #ifdef __cplusplus
    }
#endif

#endif /* !_PROGETTO_H_RPCGEN */


3.3 l'interfaccia Server

progetto_svc.c si occupa della dichiarazione dei servizi e la gestione degli id che comunicano con il client.

/*
* Please do not edit this file.
* It was generated using rpcgen.
*/

#include "progetto.h"
#include
#include /* getenv, exit */
#include
#include /* for pmap_unset */
#include /* strcmp */
#include /* setsid */
#include
#include
#include
#include /* rlimit */
#include

#ifndef SIG_PF
#define SIG_PF void(*)(int)
#endif

#ifdef DEBUG
#define RPC_SVC_FG
#endif

#define _RPCSVC_CLOSEDOWN 120
extern int _rpcpmstart; /* Started by a port monitor ? */

/* States a server can be in wrt request */

#define _IDLE 0
#define _SERVED 1

static int _rpcsvcstate = _IDLE; /* Set when a request is serviced */
static int _rpcsvccount = 0; /* Number of requests being serviced */
mutex_t _svcstate_lock; /* lock for _rpcsvcstate, _rpcsvccount */

static void _msgout(char* msg) {

     #ifdef RPC_SVC_FG
        if (_rpcpmstart)
              syslog(LOG_ERR, msg);
        else
              (void) fprintf(stderr, "%s\n", msg);
      #else
          syslog(LOG_ERR, msg);
      #endif
}

int _get_line_1(request *argp, res_list *result, struct svc_req *rqstp) {

       return (get_line_1_svc(*argp, result, rqstp));
}

void progetto_server_1(struct svc_req *rqstp, register SVCXPRT *transp) {

    union {
            request get_line_1_arg;
     } argument;
     union {
     res_list get_line_1_res;
     } result;
  bool_t retval;
  xdrproc_t _xdr_argument, _xdr_result;
  bool_t (*local)(char *, void *, struct svc_req *);

  mutex_lock(&_svcstate_lock);
  _rpcsvccount++;
  mutex_unlock(&_svcstate_lock);
      switch (rqstp->rq_proc) {
             case NULLPROC:
                  (void) svc_sendreply(transp,
                               (xdrproc_t) xdr_void, (char *)NULL);
                mutex_lock(&_svcstate_lock);
                _rpcsvccount--;
                _rpcsvcstate = _SERVED;
                mutex_unlock(&_svcstate_lock);
                return;

           case get_line:
                _xdr_argument = (xdrproc_t) xdr_request;
                _xdr_result = (xdrproc_t) xdr_res_list;
                local = (bool_t (*) (char *, void *, struct svc_req *))_get_line_1;
       break;

       default:
       svcerr_noproc(transp);
       mutex_lock(&_svcstate_lock);
       _rpcsvccount--;
       _rpcsvcstate = _SERVED;
       mutex_unlock(&_svcstate_lock);
        return;
  }
  (void) memset((char *)&argument, 0, sizeof (argument));
           if (!svc_getargs(transp, _xdr_argument, (caddr_t) &argument)) {
                  svcerr_decode(transp);
                  mutex_lock(&_svcstate_lock);
                  _rpcsvccount--;
                  _rpcsvcstate = _SERVED;
                  mutex_unlock(&_svcstate_lock);
                  return;
           }
   retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp);
           if (retval > 0 && !svc_sendreply(transp, _xdr_result, (char *)&result)) {
                  svcerr_systemerr(transp);
           }
           if (!svc_freeargs(transp, _xdr_argument, (caddr_t) &argument)) {
                  _msgout("unable to free arguments");
                  exit(1);
           }
           if (!progetto_server_1_freeresult(transp, _xdr_result, (caddr_t) &result))
                  _msgout("unable to free results");

                  mutex_lock(&_svcstate_lock);
                 _rpcsvccount--;
                 _rpcsvcstate = _SERVED;
                 mutex_unlock(&_svcstate_lock);
                 return;
           }


3.4 l'interfaccia Client

progetto_clnt.c è l'interfaccia che il client C dovrà utilizzare per eseguire la connessione RPC. Lo tralasceremo non essendo una parte importante per il tutorial su JRPC.

3.5 il sorgente XDR

progetto_xdr.c si occupa della gestione delle strutture tramite XDR. Grazie alla struttura XDR questo sorgente permette la comunicazione tra diversi linguaggi di programmazione.

/*
* Please do not edit this file.
* It was generated using rpcgen.
*/

#include "progetto.h"

bool_t
xdr_request(register XDR *xdrs, request *objp) {


  #if defined(_LP64) || defined(_KERNEL)
             register int *buf;
   #else
             register long *buf;
  #endif

    if (!xdr_int(xdrs, &objp->from))
              return (FALSE);
    if (!xdr_int(xdrs, &objp->to))
          return (FALSE);
    return (TRUE);
}

bool_t
xdr_result(register XDR *xdrs, result *objp) {


   #if defined(_LP64) || defined(_KERNEL)
           register int *buf;
    #else
           register long *buf;
    #endif

      if (!xdr_int(xdrs, &objp->number))
           return (FALSE);
      if (!xdr_string(xdrs, &objp->line, ~0))
           return (FALSE);
      if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (result), (xdrproc_t) xdr_result))
           return (FALSE);
           return (TRUE);
}

bool_t
xdr_res_list(register XDR *xdrs, res_list *objp) {


  #if defined(_LP64) || defined(_KERNEL)
    register int *buf;
   #else
   register long *buf;
   #endif

    if (!xdr_pointer(xdrs, (char **)objp, sizeof (result), (xdrproc_t) xdr_result))
       return (FALSE);
       return (TRUE);
}






JavaPortal è ideato da:    
K-Tech Logo










LICENZA



Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons

Sitemap  © 2002-2004 Copyright Information. Privacy . Today is sabato 19 giugno 2010