Il linguaggio Java come supporto ad un`architettura

COREP
Consorzio per la Ricerca e l’Educazione Permanente
Master in Tecnologia e Comunicazione Multimediale
Il linguaggio Java come supporto
ad un’architettura Client/Server
Tesi di diploma di:
Luca Martini
Dicembre 1996-Novembre 1997
Indice
Indice .................................................................................................................. 1
Introduzione ....................................................................................................... 2
Primo Capitolo: Internet, TCP/IP, e WWW............................................................. 5
Secondo Capitolo: Architetture Client/Server ........................................................13
Terzo Capitolo: Server Web, Java, CGI, ACTIVE X .................................................19
Quarto Capitolo: Conclusioni ...............................................................................23
Appendice A: Sorgente Java ................................................................................26
Appendice B: Il Calcolo della Riscrittura di Termini.................................................43
Bibliografia ........................................................................................................48
1
Introduzione
L’enorme successo di Internet, al di là degli evidenti vantaggi di aver dato
accesso ad immense quantità di informazioni tramite il più noto dei suoi servizi,
ovvero il World Wide Web, ha aperto anche nuove prospettive e possibilità per le
aziende, sia per quanto riguarda il business on line (promozione e commercio
elettronico), sia per l’organizzazione gestionale e operativa interna all’azienda
stessa. Proprio su questa seconda opportunità vogliamo porre l’attenzione, perchè
riteniamo che l’utilizzo della tecnologia Internet internamente all’azienda, ovvero
INTRANET, offra effettivi vantaggi e interessanti servizi a fronte di investimenti
modesti.
Una rete INTRANET altro non è che una rete di computer locale che utilizza lo
stesso protocollo di comunicazione di Internet (TCP-IP), e sostanzialmente gli
usuali strumenti di navigazione (browser quali Netscape, o Internet Explorer), che
hanno, come è noto, molti vantaggi: sono universali (ovvero girano su qualsiasi
piattaforma, Windows, Apple, Unix, ecc...); sono a costo zero o soggetti a una
royality modestissima; sono facilmente utilizzabili e largamente conosciuti
dall’utente.
Una rete INTRANET può contribuire a realizzare un efficiente sistema
informativo andando ad intergrarsi con quelli esistenti all’interno dell’azienda e con
le applicazioni utilizzate. Ma quali sono effettivamente i vantaggi di una INTRANET
?
I principali benefici, anche per aziende di piccole dimensioni, sono rappresentati
2
dalla possibilità di distribuire con facilità dati ed applicazioni sulla rete locale:
rapporti, listini, cataloghi, anagrafiche, posta interna, manuali, applicazioni office,
movimenti contabili, moduli di ordine che vanno ad intervenire sugli archivi
esistenti, ecc... Il tutto utilizzando lo stesso strumento di lavoro (il browser per
l’appunto).
Inoltre l’investimento per realizzare una INTRANET è particolarmente ridotto
perchè la parte Client (ovvero le stazioni di lavoro) è interamente gestita dal
browser e può indifferentemente girare su qualsiasi tipo di calcolatore o sistema
operativo.
Infine un ulteriore vantaggio è rappresentato dalla possibilità di esportare,
anche successivamente, su Internet una o più applicazioni esistenti, aprendo
quindi una finestra di propria attività sulla rete mondiale (cataloghi, listini,
commercio elettronico, ecc...).
Analizziamo in breve il contenuto dei singoli Capitoli:
Capitolo primo: Internet, TCP/IP, e WWW.
In questo Capitolo, introduciamo Internet, tracciandone la storia e lo sviluppo, e
descrivendo il suo protocollo di comunicazione (TCP/IP) e il più noto dei suoi
servizi (WWW).
Capitolo secondo: Architetture Client/Server.
Con questo capitolo vogliamo introdurre il modello Client/Server, confrontandolo
con quello tradizionale a mainframe.
Capitolo terzo: Server Web, Java, CGI, ACTIVE X.
In questo Capitolo, vengono confrontati i tre metodi software adottati dai più
importanti browser per realizzare architetture Client/Server con Internet, e
presentate le loro interazione con un Server Web.
Capitolo quarto: Conclusioni.
3
In questo Capitolo tracciamo i possibili sviluppi futuri, con particolare attenzione
all’area della Programmazione Logica e a quella del Calcolo della Riscrittura di
Termini.
Appendice A: Sorgente Java.
In
questa
Appendice,
riportiamo
alcuni
sorgenti
in
codice
Java
per
l’interfacciamento con un database Oracle, e per realizzare una connessione fra
Sever e Client per la scrittura sul Server di nuovi file HTML.
Appendice B: Il Calcolo della Riscrittura di Termini.
In questa Appendice, presentiamo il Calcolo della Riscrittura di Termini in rapporto
al modello Client/Server e all'Elaborazione Distribuita.
4
Primo Capitolo
Internet, TCP/IP, e WWW
Internet
Internet è sicuramente un autentico prodigio tecnologico, secondo alcuni il
manufatto più sofisticato mai prodotto dall'attività umana, al tempo stesso
semplice ed elegante dal punto di vista concettuale e progettuale: il mezzo finale
di comunicazione, capace di veicolare, riassumere e assimilare quelli già esistenti e
di ricondurre a sè ogni possibile, futura modalità comunicativa.
Uno strumento unico per comunicare con il mondo intero, già oggi (tramite una
dotazione tecnologica minima e alla portata di tutti) e sempre di più in un domani
che vedrà la digitalizzazione di tutte le informazioni. Uno strumento della cui
versalità e flessibilità al momento non si scorgono limiti.
Come e forse più che negli anni '80, quando con l'affermarsi del personal
computer la tecnologia informatica è entrata in tutte le case e ha rivoluzionato
tutti i settori produttivi e la stessa vita quotidiana, Internet è destinata a
sconvolgere (come già sta facendo) la nozione stessa di comunicazione, con
conseguenze sociali di vasta portata.
Ripercorriamone brevemente la storia.
Nel 1969 diviene operativa una prima versione di un progetto militare
statunitense commissionato dal Dipartimento della Difesa all’agenzia governativa
ARPA (Advanced Research Projects Agency). Lo scopo del progetto è la creazione
5
di una struttura informativa che permetta lo scambio di dati tra i vari organi della
difesa nazionale e il cui funzionamento non dipenda da nessuno dei suoi singoli
nodi, contrariamente alle reti di comunicazione tradizionali, come quella telefonica
o telegrafica: in caso di avaria (o di attacco nemico) a un nodo della rete, le
comunicazioni devono essere possibili tra tutti i centri ancora opertivi. Un ulteriore
elemento di affidabilità sarebbe stato introdotto dal supporto del collegamento,
non più unicamente su linea dedicata ma su normali linee telefoniche.
Gli scambi di informazioni, infatti, avvenivano secondo la tecnica del Circuit
Switching (Commutazione di Circuito), in genere implementata collegando ciascun
computer a linee dedicate, al di fuori degli standard elettronici e telefonici
commerciali e spesso costosissime. L'adozione della linea telefonica, su cui
viaggiano
contemporaneamente
numerosi
segnali,
ciascuno
relativo
a
comunicazioni diverse, porta alla scelta e allo sviluppo definitivo di una nuova
tecnica di trasmissione di dati detta Packet Switching (Commutazione a
Pacchetto).
Nella Commutazione a Pacchetto i dati da trasmettere vengono organizzati in
moduli indipendenti (i pacchetti), ciascuno dei quali porta con sè l'indirizzo del
mittente, quello del destinatario, e l'ordine di trasmissione, in modo da consentire
alla macchina ricevente di ricostruire l'esatta sequenza in cui i pacchetti
costituiscono il messaggio. Un approccio innovativo alla trasmissione dei dati, che
trasforma la vecchia nozione di rete (molto simile a un circuito ferroviario
rigidamente organizzato in binari unici, in cui nessun treno può superare o dare la
precedenza a un altro) in una sorta di autostrada con un gran numero di corsie, in
cui i messaggi viaggiano indipendentemente gli uni dagli altri.
Il successo della nuova rete è immediato: il progetto dell'ARPA viene assorbito
dal Defense Advanced Project Research Agency (DARPA) che riprende e aggiorna
lo sviluppo dell'originario software di protocollo del controllo di Rete (NCP,
6
Network Control Protocol). Il nuovo nato, che risponde a mutate esigenze di
commutazione tra reti eterogenee, si articola nel protocollo di controllo della
trasmissione TCP (Transmission Control Protocol) e nel protocollo Internet IP
(Internet Protocol).
TCP/IP
La spinta per lo sviluppo del protocollo TCP/IP venne data dalle nuove esigenze
nate dallo sviluppo e dall’integrazione di reti diverse, che si trovavano nella
necessità di comunicare: reti via satellite, reti via radio a commutazione di
pacchetto e naturalmente ARPAnet. Il lavoro di progettazione e sviluppo di TCP/IP
è un primo esempio “metodologia Internet”: molto semplicemente, quando c’è
bisogno di qualcosa, la si fa, la si collauda “nel mondo reale” e una volta che è
stata ottimizzata la si generalizza, definendo uno standard.
I nuovi protocolli vennero utilizzati per ARPAnet a partire dal 1° gennaio 1983,
data che per alcuni costituisce la nascita ufficiale di Internet: la maggior
affidabilità ed efficienza di TCP/IP rispetto al suo predecessore NCP furono la
causa principale della migrazione di tutte le principali Reti a commutazione di
pacchetto verso il nuovo protocollo, che si impose in breve come lo standard di
riferimento.
Il protocollo di controllo della trasmissione (Transmission Control Protocol) è la
prima interfaccia software verso la Rete e colloquia principalmente con le
applicazioni di livello superiore, quelle a diretto contatto con l’utente. Di concerto
col sistema operativo, TCP soddisfa un gran numero di esigenze dei programmi
applicativi, che basano i propri protocolli interni su servizi messi a disposizione da
TCP: è il caso del protocollo per il trasferimento di file (FTP), del protocollo
semplice per il trasporto di posta elettronica (Simple Mail Transfer Protocol, SMTP)
7
o di una sessione di TELNET (simulazione di terminale remoto). Quando avviamo
singoli applicativi che implementano queste funzioni (come Eudora, nel caso della
posta elettronica), essi si preoccupano in primo luogo di stabilire una
comunicazione col software che implementa i protocolli TCP (come Winsock
Trumpet o MacTCP) e che da quel momento è disponibile all’applicazione.
Tra le funzioni per cui un programma applicativo che ha necessità di colloquiare
in Internet può rivolgersi a TCP, vi sono la sua gestione dei dati orientata alla
connessione, il trasferimento dei dati, il controllo del flusso di trasmissione e il
trasferimento fullduplex (bidirezionale simultaneo). Una caratteristica di TCP che
non tutti i programmi sfruttano, ma che è incorporata nella definizione dello
standard del protocollo, è quella di specificare livelli di sicurezza e di priorità per la
connessione.
Questo per quanto riguarda il colloquio fra TCP e lo strato superiore. Lo
standard TCP non comprende infatti alcuna specifica per quanto riguarda le
comunicazioni con lo strato inferiore, sottointendendo che questo è in grado di
scambiare informazioni con TCP in modo asincrono.
Il protocollo Internet si occupa di fornire tutti i servizi necessari alla gestione del
traffico tra l’utente e la rete sottostante, nonchè (installato sui server di rete e sui
gateway) tra le varie sottoreti attraverso cui i dati transitano per arrivare a
destinazione. Si tratta di un cosiddetto “protocollo senza connessione” che non
prevede alcun controllo sull’integrità e sulla completezza dei dati dalla partenza
alla destinazione e che deve perciò appoggiarsi a un protocollo di livello superiore,
come appunto TCP. Questo significa anche che IP è un protocollo relativamente
semplice e “ignorante”: occupandosi esclusivamente della confezione e dello
smistamento
dei
pacchetti
(o
“datagrammi”),
nonchè
del
loro
instradamento/ricezione, esso possiede ben pochi indizi sul funzionamento della
8
Rete o delle reti sottostanti, il che rende queste ultime relativamente indipendenti
da IP stesso.
In Internet è fondamentale distinguere chiaramente alcune nozioni che
vengono spesso confuse. Un nome è un identificatore alfanumerico (cioè una
sequenza di caratteri e cifre) che indica una certa entità, quali un computer, un
programma, una persona, una rete, indipendentemente dalla loro dislocazione
fisica. Un indirizzo è un altro identificatore che fornisce informazioni di natura
molto più approfondita e specifica a proposito di una certa risorsa, quali la sua
posizione fisica o logica nella Rete. Un percorso è l’insieme delle informazioni e
delle modalità da seguire necessarie al reperimento di una posizione fisica (sia
essa un indirizzo o meno).
Non è in realtà una distinzione difficile, anche perchè si basa sul modello
postale/telefonico che tutti conosciamo e che in effetti costituisce ancor oggi l’idea
alla base della maggior parte delle sottoreti che afferiscono a Internet.
Nella pratica, l’utente utilizza di solito un nome per identificare il destinatario di
una certa comunicazione; un name server (o server di nomi) risale dal nome
all’indirizzo del destinatario, indirizzo da cui si ricostruisce il percorso fisico
attraverso un protocollo di routing.
Si tratta di un’impostazione che consente una grande elasticità nella gestione
delle risorse di rete, permettendo a sistemisti e amministratori di sistemi di
riconfigurarle e di ottimizzarle senza che ciò tocchi in alcun modo gli utenti finali.
Anche se l’utente finale ha a che fare solitamente col nome della risorsa di rete
a cui vuole accedere (per esempio, un altro computer di rete), la prima cosa di cui
si incarica il name server residente sull’host dell’utente è la sua traduzione in un
indirizzo IP, cioè l’indirizzo di rete comprensibile agli strati successivi di software
9
che implementano i protocolli di trasmissione. Le reti TCP/IP implementano
indirizzi a 32 bit che codificano la rete di appartenenza della risorsa (indirizzo di
rete) e l’host che la supporta (indirizzo di host). La struttura dell’indirizzo IP è
quindi: indirizzo IP=indirizzo di rete+indirizzo di host, a cui i 32 bit disponibili
possono essere riservati in più modi, secondo la ripartizione seguente:
Classe A
[rete.host.host.host] 0-Rete (7 bit)-Indirizzo locale (24 bit)
Classe B
[rete.rete.host.host]
10-Rete (14 bit)-Indirizzo locale (16 bit)
Classe C
[rete.rete.rete.host]
110-Rete (21 bit)-Indirizzo locale (8 bit)
Classe D
[non applicabile]
1110-Indirizzo multicast (28 bit)(16 bit)
Ricordando che N bit permettono di codificare 2^N numeri, è facile constatare
che le diverse classi di indirizzamento riflettono esigenze di bilanciamenti reti/host
alquanto diverse. Gli indirizzi di classe A riservano 24 bit all’indirizzamento di rete e
7 all’indirizzamento dell’host. Questo significa che permettono di indirizzare
2^7=128 reti (in realtà 126, perchè i valori 0 e 127 sono riservati) e
2^24=1677216 host (in reltà, 1677124).
In formato binario, un indirizzo IP (di classe C, per esempio) avrà un formato
del tipo
11000001 11001111 00000010 00011111
dove è stata evidenziata la suddivisione nei 4 byte che lo costituiscono. Di solito
i byte vengono rappresentati in forma decimale e separati da un punto. Così, il
nostro indirizzo diventa:
193.207.2.31
una forma già molto più familiare ai frequentatori di Internet. In questo
formato, 193.207.2 è l’identificatore di rete della risorsa, mentre 31 è l’indirizzo
dell’host.
WWW
10
La nascita di un mercato Internet diffuso, in cui ciascuno può disporre di una
propria connessione, ha portato all’esplosione più che esponenziale della richiesta
di gestione e manutenzione dei servizi legati alla Rete. Come avviene sempre in
questi casi, a tale richiesta è subito corrisposta anche una tendenza alla
semplificazione degli ambienti già esistenti e allo sviluppo di nuovi, maggiormente
amichevoli e di rapido apprendimento.
Così il tempo e i costi di avviamento di un nodo (hardware, software e risorse
umane) hanno subito una diminuizione drastica e continuano a scendere
costantemente.
Il caso più clamoroso è quello del World Wide Web, la ragnatela mondiale ormai
costituita da decine di migliaia di siti in tutto il mondo.
Com’è noto, non è solo una delle tecnologie Internet più recenti, sviluppata
presso il CERN di Ginevra negli anni 1989/91, ma anche la più diffusa e popolare,
e che molti utenti letteralmente identificano con Internet. I motivi sono
abbastanza chiari: il protocollo HTTP (Hyper Text Transfer Protocol) su cui si basa
WWW, supportato da browser ormai popolarissimi come Mosaic, Netscape
Navigator o Microsoft Explorer, consente la trasmissione di dati e informazioni con
una ricchezza in precedenza impensabile, realizzando un’effettiva ipertestualità del
messaggio. In un unico documento Web convivono testo, immagini, e suoni, in un
amalgama assolutamente inedito di dati e informazioni che attraverso la Rete
vengono messi a disposizione.
La tecnologia Web è nata in anni recenti ed è già “adulta”, nel senso che sia i
programmi client che la implementano che gli ambienti di sviluppo (software di
installazione e di gestione del server Web, editor HTML, ecc...) fin dall’inizio sono
stati sviluppati con interfacce grafiche evolute e “amichevoli”. Questo fatto ha
giocato una parte considerevole nell’incredibile risposta che Web ha avuto in tutto
11
il mondo e che ha portato a una successiva, ulteriore diffusione degli strumenti di
sviluppo e manutenzione: oggi la realizzazione di un server Web, cioè di una
macchina su cui realizzare siti Web, è alla portata sia economica che tecnologica di
praticamente chiunque desideri farlo. L'enorme richiesta per questo tipo di
installazioni ha infatti portato alla nascita di ambienti di sviluppo sotto piattaforme
commerciali (quali Windows e MacOS) togliendo alle workstation Unix il monopolio
sulla gestione dei servizi Internet, e in particolare dei siti Web.
Un esempio è fornito dall'attenzione della Microsoft per ogni tipo di tecnologia
Internet e per quella WWW in particolare, considerata strategica. Il sistema
operativo Windows NT, per esempio, era sì nato come possibile alternativa a
concorrenti come OS/2 e Unix come sistema per workstation/server di Rete
(locale, naturalmente), ma si è definitivamente affermato con la nascita di una
vera e propria nuova "figura" di workstation, quella del server Internet.
Limitandoci per semplicità al caso in cui si voglia implementare un server Web,
oggi una configurazione basata su Windows NT rappresenta una scelta praticabile
da chiunque, sia per costi hardware/software che per competenze necessarie: la
documentazione tecnica è infatti abbondante e di facile reperibilità.
12
Secondo Capitolo
Architetture Client/Server
Il modello Client/Server
L'elaborazione Client/Server è oggi la tecnologia che sta compiendo i maggiori
progressi nel settore dell'informatica: il suo utilizzo è destinato a diffondersi e a
ridefinire la modalità di elaborazione e produzione delle applicazioni negli anni
Novanta e oltre. Ora che l'evoluzione del mercato dell'informatica punta
decisamente in direzione di personal computer potenti ma economici, il momento
è propizio perchè l'elaborazione Client/Server possa sbocciare. Sempre più
frequentemente, i nuovi PC vengono collegati in rete per formare ambienti
interconnessi di rete locali (LAN). Sfruttando appieno la LAN e tutti i suoi
componenti elaborativi, la tecnologia Client/Server è diventata un'alternativa
possibile all'elaborazione mainframe centralizzata; questo non significa tuttavia
che i mainframe siano finiti o sorpassati.
L'elaborazione Client/Server fa leva sull'enorme potenziale degli ambienti LAN
interconnessi. La possibilità di eseguire un programma in più macchine comporta
un potenziale incremento delle prestazioni e della scalibilità.
L'elaborazione Client/Server definisce un nuovo metodo di elaborazione,
rimettendo in discussione le modalità precedenti di esecuzione e gestione dei
programmi.
I programmi tradizionali vengono eseguiti in una singola macchina: le
13
applicazioni possono essere mainframe, nel qual caso tutta l'elaborazione viene
svolta nel computer mainframe centrale, oppure autonome, nel qual caso tutta
l'elaborazione avviene in un personal computer o in una stazione di lavoro.
Le applicazioni Client/Server sono diverse, in quanto vengono eseguite sia in un
client sia in un server e fondono le parti migliori delle applicazioni autonome e di
quelle mainframe in un ambiente coesivo.
Più precisamente:
Client/Server è la suddivisione di un programma applicativo in due componenti
logicamente separati, ciascuno dei quali assolve mansioni molto diverse. In
generale, un client invia al server la richiesta di eseguire un lavoro, mentre al
server spetta elaborare le richieste del client e restituire i risultati. Questo processo
avviene quasi sempre tra due computer fisicamente separati, in qualche tipo di
infrastruttura fisica di LAN. Solitamente, gli elaboratori server sono molto più
capienti e più veloci e sono quindi idonei per gestire il lavoro proveniente da altri
sistemi.
La tecnologia client/server è costituita da programmi client, o front-end, che
coordinano la logica delle applicazioni con un'applicazione server, o back-end,
utilizzando la LAN come mezzo di comunicazione. Questa suddivisione delle
applicazioni consente l'elaborazione del lavoro da parte di due computer invece di
uno solo. L'evoluzione verso l'informatica distribuita può addirittura determinare il
coinvolgimento di molti server nell'elaborazione back-end della logica delle
applicazioni. La combinazione di questi sistemi offre enormi possibilità di ottenere
applicazioni ad alte prestazioni e un grado elevato di scalabilità.
La flessibilità della tecnologia client/server consente di eseguire l'elaborazione
nel punto in cui questa risulta più efficiente. Molti sono i vantaggi offerti dalla
possibilità di ospitare i componenti logici delle applicazioni nel client o nel server:
14
grazie alla migrazione di parti del programma applicativo tra il client e il server, lo
sviluppatore può determinare il conseguimento di risultati ottimali. In alcuni
prodotti di sviluppo client/server, la posizione dell'esecuzione può addirittura
essere una decisione run-time.
Poichè l'elaborazione può essere situata in qualsiasi punto di una rete, la
tecnologia client/server offre la possibilità di scalare in modo efficiente. Per
ottenere il giusto equilibrio di client e server, un componente di un’applicazione
dovrebbe essere eseguito in un server solo quando l'elaborazione centrale del
lavoro costituisce la procedura più efficiente; per esempio, la collocazione di parti
di un'applicazione in un server in cui risiedono alcuni dati centrali è un'ottima
scelta: i requisiti della rete potrebbero infatti essere meno rigidi perchè la logica
dell'applicazione che interfaccia con i dati centrali sarebbe situata sulla macchina
con i dati e pertanto questi ultimi non verrebbero trasmessi attraverso la LAN.
L'elaborazione client/server è molto diversa dall'elaborazione mainframe. Dal
punto di vista della logica, vi sono molte differenze, ma anche alcune
caratteristiche simili: entrambe elaborano centralmente la logica delle applicazioni
per conto di utenti remoti; inoltre, questi ultimi sono solitamente connessi
mediante una qualche forma di rete fisica. Dal punto di vista dell'architettura, la
differenza
più
rilevante
tra
l'impostazione
client/server
e
l'impostazione
centralizzata mainframe è la seguente: con l'elaborazione client/server, i client
sono intelligenti, in quanto possiedono una vera e propria CPU e sono in grado di
elaborare
dati
reali,
mentre
i
terminali
mainframe
di
norma
fungono
semplicemente da input/output di un computer mainframe che elabora
centralmente
la
logica
delle
applicazioni.
I
limiti
insiti
nell'impostazione
centralizzata mainframe hanno indotto molte aziende a considerare il downsizing
15
delle loro applicazioni e il passaggio a un ambiente client/server.
E' tuttavia importante notare che, con l'aumento della quantità di lavoro del
server, il sistema tende ad avvicinarsi all'impostazione mainframe: poichè la
tecnologia è solitamente realizzata su macchine di piccole dimensioni, le
prestazioni delle applicazioni possono di fatto subire un peggioramento in caso di
utilizzo eccessivo del server o di vincolo delle sue risorse. E' essenziale bilanciare il
carico di lavoro del server e prevedere alcuni strumenti di scalabilità per consentire
il passaggio a sistemi di dimensioni maggiori.
La tendenza ad adottare l'elaborazione client/server è storica: innanzitutto, i
sistemi operativi sono stati suddivisi in vari componenti e la loro interazione è
stata gestita come una serie di processi client e server eseguiti sulla stessa
macchina; successivamente, sono stati introdotti file system di rete e la risposta
alle richieste di dati o file è stata affidata a una macchina remota: in tali ambienti,
le richieste di dati venivano instradate attraverso la rete e gestite da un file server
di rete. I software di rete per file server centralizzati, quali Novell NetWare, si
avvalgono della tecnologia client/server da oltre un decennio: questi sistemi hanno
avuto una notevole diffusione negli anni Ottanta, con l'avvento e il rapido sviluppo
delle LAN.
In tempi più recenti, molte applicazioni sono state realizzate come tecnologia
client/server.
Quest'ultima non consiste solo semplicemente nei componenti del sistema che
assolvono mansioni quali la condivisione dei file, ma nel vero e proprio spazio delle
applicazioni che diventa client/server; di fatto, l'applicazione client/server
attualmente più diffusa è il database relazionale: quasi tutti i produttori di
database hanno una versione client/server del loro prodotto. Con tali prodotti, le
query (interrogazioni) generali (di norma SQL) vengono effettuate nei confronti
dei database server: le richieste sono formulate nel client e trasmesse al server
16
per l'esecuzione; il server elabora le query confrontandole con il database
memorizzato localmente, quindi restituisce i risultati al client attraverso la rete. Il
sistema di gestione dei database si occupa dell'interazione dei componenti client e
server.
La tendenza in atto nella tecnologia client/server è la distribuzione della logica
delle applicazioni: è stato dimostrato che l'elaborazione client/server offre un
sensibile miglioramento delle prestazioni per quanto riguarda la gestione delle
richieste di file e database. Attualmente la maggior parte dei sistemi operativi è in
grado di eseguire l'elaborazione client/server.
Come l'elaborazione client/server, l'elaborazione distribuita comporta la
distribuzione del lavoro tra più macchine; è tuttavia più ampia, in quanto molte
macchine possono elaborare il lavoro per conto degli apparecchi client.
L'elaborazione
distribuita
può
essere
considerata
come
un'elaborazione
client/server con un solo client e molti server. Nel caso dell'elaborazione distribuita
il termine server indica semplicemente un programma che risponde alle richieste e
fornisce il risultato dei calcoli a un'unità client richiedente.
Il VDR
La gestione organica della documentazione di commessa assume molta
importanza all’interno dell’azienda, in quanto permette il controllo dei vari processi
di progettazione tecnica, approvvigionamento, costruzione e montaggio (questi
ultimi legati alla disponibilità di disegni e specifiche tecniche).
Attualmente tale gestione è effettuata attraverso l’utilizzo di più procedure
informatiche tra loro scollegate e con basi dati diverse; ciò non permette una
visione globale delle attività di progettazione nè dello stato di avanzamento dei
diversi documenti.
17
Utilizzando una Intranet, cioè una rete locale basata sul protocollo TCP/IP di
Internet, si vuole definire un sistema per la gestione della Trasmissione/Ricezione
della documentazione di commesse, denominato Vendor Document Register:
“V.D.R. (Vendor Document Register), Strumento informatizzato di gestione della
documentazione di commessa” (la gestione va intesa sia verso l’interno, cioè Uffici
Tecnici, sia verso l’esterno, cioè Clienti e Fornitori).
Scopo del progetto è la gestione della storia di tutta la documentazione
associata ad una determinata commessa, individuando in essa due fasi, una di
definizione, fatta una sola volta nella vita di una commessa, ed una di invio,
ripetuta più volte.
Il progetto è stato sviluppato secondo il modello Client/Server, con le
informazioni relative alle varie tipologie di dati che risiedono su un database
Oracle, garantendo portabilità del sistema su qualsiasi tipo di stazione
adeguatamente attrezzata.
La componente Server è una macchina con sistema operativo Unix, predisposta
con server http per rendere possibile l’interrogazione della macchina da utenze
remote. Inoltre è prevista una base dati Oracle per l’archiviazione delle
informazioni con precompilatore per codice C. Le componenti Client sono costituite
da PC con almeno 16 Mb di RAM con sistema operativo Windows 95 o Windows
NT e Netscape Navigator 3.0 o superiore.
La procedura VDR, operativa su un’architettura di tipo Client/Server, con le
informazioni concentrate sul Server, rende accessibile le informazioni a tutti gli
utenti collegati in rete con un PC Client, ed al tempo stesso garantisce una
sufficiente sicurezza e facilità di gestione
18
Terzo Capitolo
Server Web, Java, CGI, Active X
Server Web
Un Server Web è un programma in funzione su una macchina direttamente
connessa a Internet, in attesa che un browser Web si colleghi e richieda un file.
Quando giunge tale richiesta, il server individua il file e lo invia al browser. Il
Server Web e il browser Web comunicano utilizzando il protocollo HTTP (Hyper
Text Transfer Protocol), un protocollo appositamente creato per il trasferimento di
documenti ipertestuali su Internet. Solitamente i Server Web vengono chiamati
HTTPD, dove la "D" finale sta per "daemon", termine UNIX che identifica un
programma che funziona in background e rimane in attesa di richieste: quando un
daemon riceve una richiesta, si risveglia, elabora tale richiesta e torna in
background.
Java
Java è un linguaggio di programmazione simile al C++, portabile su qualunque
sistema dotato di una apposita Macchina Java Virtuale in grado di interpretare il
codice intermedio con cui è composto il linguaggio stesso. Il risultato è quello di
avere programmi compatti, anche se talvolta lenti, che funzioneranno su
qualunque tipo di PC.
Il compilatore Java compila, infatti, il codice sorgente in una rappresentazione
19
intermedia chiamata “bytecode Java”. Il termine bytecode sta ad indicare che ogni
parte di un programma Java viene tradotta in una sequenza di byte che
rappresentano le istruzioni per una Macchina Java Virtuale
Il codice di programma viene sempre controllato dalla Macchina Java Virtuale,
senza la quale nessun programma Java può funzionare. Questa Macchina è
integrata nel browser di Internet, oppure è installata come programma
indipendente sul disco fisso. Nel primo caso i programmi Java non hanno
possibilità di scrittura sul disco fisso e non possono nemmeno essere eseguiti
programmi esterni. Nel secondo caso il programma Java viene prima caricato
tramite Internet e poi eseguito con la Macchina Java Virtuale. Questa operazione
non è automatica ed è quindi sotto il controllo esterno. I dati locali potranno
essere letti e scritti solo previo autorizzazione esterna.
CGI
Gli script CGI (Common Gateway Interface) rappresentano un metodo utilizzato
per eseguire sul server Web un programma che si basa sull’input fornito dal
browser. Gli script CGI consentono di rendere interattive le pagine Web, ovvero di
ricercare un oggetto in un database, di offrire commenti riguardanti ciò che si
legge o di selezionare un oggetto da una scheda ottenendo una risposta specifica.
Uno script CGI è semplicemente un programma in esecuzione su un server Web
e che viene attivato dall’input fornito da un browser. Spesso lo script CGI
rappresenta l’anello di congiunzione fra il server e qualche altra applicazione
eseguibile sul sistema, ad esempio un database.
Gli script CGI possono assumere diverse forme a seconda del supporto offerto
dal server Web: possono essere programmi compilati o file batch o qualsiasi altro
tipo di file eseguibile. Gli script CGI possono essere utilizzati in due modi: come
azione (ACTION) di una scheda o come un link diretto ad una pagina.
20
Gli script CGI vengono richiamati dal server sulla base di informazioni ricevute
dal browser:
•
Un indirizzo URL punta a uno script CGI nello stesso modo in cui
potrebbe puntare a qualsiasi altro file situato sul server, ad esempio un
documento o un’immagine. Normalmente l’indirizzo URL si trova nella parte
ACTION di una scheda Web. Il browser richiede tale indirizzo URL al server così
come farebbe con qualsiasi altro documento.
•
Il server riceve la richiesta, nota che l’indirizzo URL punta a un file script
(sulla base del nome o della posizione in cui è memorizzato il file a seconda del
server) ed esegue tale script.
•
Lo script esegue qualche azione sulla base dell’eventuale input ricevuto
dal browser. L’azione può essere l’interrogazione di un database, il calcolo di un
valore o semplicemente l’esecuzione di un altro programma installato sul sistema.
•
Lo script poi formatta il risultato in modo comprensibile per il server
Web.
•
Il server Web riceve il risultato dallo script e lo trasmette al browser che
lo formatta e visualizza per il lettore.
Active X
Gli Active-X Control non sono altro che programmi che vengono caricati tramite
Internet ed eseguiti con Microsoft Internet Explorer. Come tutti gli altri programmi
Windows, anche i programmi Active-X hanno accesso a tutte le risorse del sistema
e possono eseguire qualsiasi operazione, ad esempio riprodurre un video o
cancellare dei dati.
In Active-X le brecce nella sicurezza sono già programmate nel concetto base.
Se il programma si trova sul disco fisso, è fuori da ogni controllo esterno. Il
programma Active-X viene attivato da un paio di semplici righe di codice HTML ed
21
entra in azione senza alcun intervento esterno.
22
Quarto Capitolo
Conclusioni
Se prendiamo in esame l’evoluzione degli elaboratori, anche solo facendo
riferimento agli ultimi due o tre decenni, possiamo notare due fatti fondamentali
strettamente collegati fra loro: l’aumento della potenza dell’hardware, e un
continuo e veloce miglioramento delle modalità di comunicazione dell’uomo con la
macchina.
I linguaggi di programmazione e, in generale, gli ambienti di lavoro integrati,
offrono all’utente un approccio “amichevole”, svincolandolo dalla gestione di molti
problemi tecnici e permettendogli di concentrarsi soprattutto sulla logica delle
applicazioni.
Il prossimo obbiettivo, ancora in fase di studio, è quello di produrre computer
capaci di misurarsi cin l’intelligenza e le conoscenze proprie della mente umana. Si
vuole che l’utente possa dialogare con il computer senza essere più costretto allo
sforzo di adattamento che invece è ancora oggi necessario.
Per raggiungere questo scopo, non basta aumentare la potenza delle macchine
o perfezionare il software; si tratta, invece, di progettare elaboratori che abbiano
un’architettura più attuale, con molti processori, in modo che sia possibile ottenere
sistemi intelligenti basati sulla conoscenza. Proprio intorno a questo obbiettivo
ruotano i programmi di ricerca rivolti alla progettazione degli elaboratori della
Quinta Generazione.
23
Una caratteristica fondamentale dei nuovi sistemi di elaborazione è costituita da
una base della conoscenza, di grandi dimensioni e sottoposta a un continuo
aggiornamento, realizzato da un sottosistema di processori.
Naturalmente, nasce il problema di mettere a punto tecniche valide per
strutturare e memorizzare questa conoscenza, in modo che sia possibile
consultarla e aggiornarla in tempi accettabili. Per imitare il funzionamento della
mente umana, occorre che la macchina abbia la capacità di comprendere la
descrizione di un problema e di progettarne la soluzione.
Il grande passo in avanti consisterebbe nel dare all’utente la possibilità di
formulare quesiti in linguaggio naturale, senza l’obbligo di formalizzarli secondo
schemi rigidi, come quelli imposti dai sistemi attuali. E’ di particolare importanza,
allora, riuscire a riprodurre certi meccanismi di ragionamento e di apprendimento.
Per questo motivo, un elemento fondamentale nell’architettura dei nuovi
calcolatori è rappresentato da un sottosistema di processori dedicato all’inferenza,
cioè al processo attraverso il quale un elaboratore ricava delle conclusioni sulla
base di un certo insieme di conoscenze (sono tecniche tipicamente usate nel
campo dell’intelligenza artificiale). Addirittura, la potenza di un computer di questo
tipo viene espressa in lips (inferenze logiche per secondo).
Proprio allo scopo di ottenere un livello più elevato di prestazioni, molti studi
puntano alla realizzazione di nuove tecniche per le elaborazioni in parallelo.
Con il termine processo si intende un programma in esecuzione, e si ha un
parallelismo reale quando, in presenza di più processori, avviene l'esecuzione
contemporanea di più processi. Addirittura, lo stesso processo può essere
scomposto in più parti, che vengono poi eseguite nello stesso tempo. Tuttavia,
non sempre tutti i processi e tutte le istruzioni di un processo possono essere
eseguite nello stesso tempo, e per utilizzare in modo efficiente le possibilità di
elaborazioni in parallelo, occorrono sistemi di gestione molto sofisticati.
24
Un altro campo di ricerca che desta grande interesse è quello che riguarda le
modalità di comunicazione tra il computer e i suoi utenti. L'obbietttivo di creare
un'interfaccia intelligente, che permetta l'uso di immagini e di linguaggi naturali (o,
almeno, di loro sottoinsiemi), assume molta importanza soprattutto in previsione
di un'utenza sempre più vasta, formata anche da persone non esperte.
L'interpretazione automatica di un linguaggio naturale presenta molte difficoltà,
perchè spesso accade che una frase abbia più interpretazioni possibili. Mentre, per
un essere umano è generalmente possibile scegliere l'interpretazione giusta in
base al contesto, ciò non è altrettanto facile quando si applicano procedimenti
automatici, anche nel caso in cui si operi con un vocabolario più ristretto. D'altra
parte, per poter comunicare con un elaboratore in un linguaggio naturale,
occorrerebbe "istruirlo" a interpretare il significato delle frasi e a fornire risposte
appropriate, sempre nello stesso linguaggio.
25
Appendice A
Codice sorgente Java
import java.awt.*;
import java.io.*;
import jdbc.sql.*;
import jdbc.math.*;
public class Connection {
private static Connection conn;
private static Statement stmt_S;
private static Statement stmt_I;
private static Statement stmt_D;
private static Statement stmt_U;
public static void Connection() {
String driver_class = "oracle.jdbc.dnlddriver.OracleDriver";
String connect_string = "jdbc:oracle:dnldthin:@rs4edp:1521:MIDACON";
try {
if (conn == null) {
System.out.println("Load the JDBC driver");
26
Class.forName (driver_class);
System.out.println("Connect to the database "+connect_string);
conn = DriverManager.getConnection (connect_string, "system",
"manager");
System.out.println("Connect to the database "+connect_string+ "done");
stmt_S = conn.createStatement ();
stmt_I = conn.createStatement ();
stmt_D = conn.createStatement ();
stmt_U = conn.createStatement ();
}
} catch (Exception e) {
System.out.println("error "+e);
}
}
public static ResultSet Search(String query) {
ResultSet rset;
try {
rset=stmt_S.executeQuery(query);
} catch (Exception e) {
System.out.println(e.getMessage());
errore error=new errore(new Frame());
error.campo1.setText("ERRORE:");
error.campo2.setText(e.getMessage());
error.show();
27
}
return rset;
}
public static boolean Insert(String query) {
try {
ResultSet rset=stmt_I.executeQuery (query);
return(true);
} catch (Exception e) {
System.out.println(e.getMessage());
if (e.getMessage().startsWith("ORA-00001")) {
errore error=new errore(pri.app);
error.campo1.setText("Errore");
error.campo2.setText("Record gia esiste");
error.show();
}
else
{
errore error=new errore(pri.app);
error.campo2.setText(e.getMessage());
error.show();
}
return(false);
}
}
28
public static boolean Update(String query) {
try {
ResultSet rset=stmt_U.executeQuery (query);
return(true);
} catch (Exception e) {
if (e.getMessage().startsWith("ORA-00001"))
{
errore error=new errore(pri.app);
error.campo1.setText("Errore");
error.campo2.setText("Record gia esiste");
error.show();
}
else
{
errore error=new errore(pri.app);
error.campo2.setText(e.getMessage());
error.show();
}
return(false);
}
}
public static boolean Delete(String query) {
try {
ResultSet rset=stmt_D.executeQuery (query);
return(true);
29
} catch (Exception e) {
System.out.println(e.getMessage());
errore error=new errore(new Frame());
error.campo2.setText(e.getMessage());
error.show();
return(false);
}
}
}
30
import java.awt.*;
import java.util.*;
import java.io.*;
import java.net.*;
import jdbc.sql.*;
public class Client_VDR {
private static Socket channel=null;
private static DataOutputStream os=null;
private static DataInputStream is=null;
final static String size_header="2";
final static String size_data="1";
final static String height="30";
private static Hashtable sez_descr=new Hashtable();
private static int righe_IMP2,righe_IMP3,righe_IMP4,righe_IMP5;
private static byte TDIMP_height=25;
private static byte num_righe=24;
private static StringTokenizer list[]=new StringTokenizer[3];
private static void THVDR_List(String comm,DataOutputStream os) throws Exception {
os.writeBytes("<tr align=\"center\" valign=\"top\">\n");
os.writeBytes("<th rowspan=1 colspan=8>\n");
os.writeBytes("<table noborder align=\"center\" cellspacing=\"0\" cellpadding=\"6\"
bordercolor=\"Black\">\n");
os.writeBytes("<tr align=\"center\">\n");
os.writeBytes("<td rowspan=2 colspan=1 valign=\"top\" height=\""+height+"\"><img
31
src=\"ge.gif\"><img src=\"Sprite7.gif\"><br>Firenze</td>\n");
os.writeBytes("<td rowspan=1 colspan=1 valign=\"top\"
height=\""+height+"\"><EM><B><FONT size=6>\n");
os.writeBytes("VENDOR DOCUMENT LIST\n");
os.writeBytes("</FONT></B></EM></td>\n");
os.writeBytes("</tr>\n");
os.writeBytes("<tr align=\"center\">\n");
.writeBytes("<td align=\"left\" height=\""+height+"\"><EM><B><FONT size=4>\n");
os.writeBytes("N° Commessa N.P. :"+comm+"\n");
os.writeBytes("</FONT></B></EM></td>\n");
os.writeBytes("</tr>\n");
os.writeBytes("</table>\n");
os.writeBytes("</th>\n");
os.writeBytes("</tr>\n");
os.writeBytes("<tr align=\"center\" valign=\"top\">\n");
os.writeBytes("<th rowspan=1 colspan=1 height=\"60\" width=\"60\"><font
size=\""+size_header+"\"><b><i>Posizione</i></b></font></th>\n");
os.writeBytes("<th rowspan=1 colspan=1 height=\"60\" width=\"280\"><font
size=\""+size_header+"\"><b><i>Titolo</i></b></font></th>\n");
os.writeBytes("<th rowspan=1 colspan=1 height=\"60\" width=\"100\"><font
size=\""+size_header+"\"><b><i>N° Documento<br>NP</i></b></font></th>\n");
os.writeBytes("<th rowspan=1 colspan=1 height=\"60\" width=\"100\"><font
size=\""+size_header+"\"><b><i>N° Documento<br>Cliente</i></b></font></th>\n");
os.writeBytes("<th rowspan=1 colspan=1 height=\"60\" width=\"100\"><font
size=\""+size_header+"\"><b><i>Descrizione<br>Documento<br>informatico</i></b></font>
</th>\n");
os.writeBytes("<th rowspan=1 colspan=1 height=\"60\" width=\"50\"><font
32
size=\""+size_header+"\"><b><i>Penale</i></b></font></th>\n");
os.writeBytes("<th rowspan=1 colspan=1 height=\"60\" width=\"70\"><font
size=\""+size_header+"\"><b><i>Pagamento</i></b></font></th>\n");
os.writeBytes("<th rowspan=1 colspan=1 height=\"60\" width=\"30\"><font
size=\""+size_header+"\"><b><i>Note</i></b></font></th>\n");
os.writeBytes("</tr>\n");
}
private static void THVDR_Note(String comm,DataOutputStream os) throws Exception {
os.writeBytes("<tr align=\"center\" valign=\"top\">\n");
os.writeBytes("<th rowspan=1 colspan=2>\n");
os.writeBytes("<table noborder align=\"center\" cellspacing=\"0\" cellpadding=\"6\"
bordercolor=\"Black\">\n");
os.writeBytes("<tr align=\"center\">\n");
os.writeBytes("<td rowspan=2 colspan=1 valign=\"top\" height=\""+height+"\"><img
src=\"ge.gif\"><img src=\"Sprite7.gif\"><br>Firenze</td>\n");
os.writeBytes("<td rowspan=1 colspan=1 valign=\"top\"
height=\""+height+"\"><EM><B><FONT size=6>\n");
os.writeBytes("VENDOR DOCUMENT REGISTER\n");
os.writeBytes("</FONT></B></EM></td>\n");
os.writeBytes("</tr>\n");
os.writeBytes("<tr align=\"center\">\n");
os.writeBytes("<td align=\"left\" height=\""+height+"\"><EM><B><FONT size=4>\n");
os.writeBytes("N° Commessa N.P. :"+comm+"<br>NOTE :\n");
os.writeBytes("</FONT></B></EM></td>\n");
os.writeBytes("</tr>\n");
33
os.writeBytes("</table>\n");
os.writeBytes("</th>\n");
os.writeBytes("</tr>\n");
os.writeBytes("<tr align=\"center\" valign=\"top\">\n");
os.writeBytes("<th rowspan=1 colspan=1 width=\"20%\" height=\""+height+"\"><font
size=\""+size_header+"\"><b><i>N° nota</i></b></font></th>\n");
os.writeBytes("<th rowspan=1 colspan=1 height=\""+height+"\"><font
size=\""+size_header+"\"><b><i>Nota</i></b></font></th>\n");
os.writeBytes("</tr>\n");
}
public static void StampaVDR_List(Form1 app,StringTokenizer pr_doc,String comm) throws
Exception {
int righe_primapagina1=10;
int righe_primapagina2=11;
String st,query;
ResultSet rset;
int cont,origine;
Hashtable ci_doc=new Hashtable();
boolean notEOS=false;
channel=new Socket("rs3edp",22500);
os=new DataOutputStream(channel.getOutputStream());
is=new DataInputStream(channel.getInputStream());
query="select ci_doc,descr from coddocinf_v";
rset=conect.Search(query);
34
while (rset.next())
ci_doc.put(rset.getString(1),rset.getString(2));
query="select pos,tit,cod_doc,ndoc_cl,ci_doc,pen_doc,pag_doc,note from
gendoc_v where pr_doc in (-1";
while (pr_doc.hasMoreElements())
query=query+","+pr_doc.nextToken();
query=query+") order by pos asc";
rset=conect.Search(query);
if (channel!=null && os!=null && is!=null) {
query="select cod_not,descr from notecom_v where comm='"+comm+"'
and cod_not in ('$$'";
os.writeBytes("INIZIO\n");
os.writeBytes("<html>\n");
os.writeBytes("<head>\n");
os.writeBytes("<title>Vendor Document List</title>\n");
os.writeBytes("</head>\n");
os.writeBytes("<body bgcolor=\"white\">\n");
os.writeBytes("<P align=center>\n");
os.writeBytes("<table border align=\"center\" cellspacing=\"0\"
cellpadding=\"6\" bordercolor=\"Black\" width=\"100%\">\n");
THVDR_List(comm,os);
cont=0;
do {
while ((notEOS=rset.next()) && (cont<righe_primapagina1)) {
cont++;
35
os.writeBytes("<tr align=\"left\" valign=\"top\">\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"60\"><font size=\""+size_data+"\">"+(rset.getString(1)==null?"":rset.getString(1))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"280\"><font
size=\""+size_data+"\">"+(rset.getString(2)==null?"-":rset.getString(2))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"100\"><font
size=\""+size_data+"\">"+(rset.getString(3)==null?"-":rset.getString(3))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"100\"><font
size=\""+size_data+"\">"+(rset.getString(4)==null?"-":rset.getString(4))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"100\"><font
size=\""+size_data+"\">"+(rset.getString(5)==null?"-":((String)
ci_doc.get(rset.getString(5))))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"50\"><font size=\""+size_data+"\">"+(rset.getString(6)==null?"":rset.getString(6))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"70\"><font size=\""+size_data+"\">"+(rset.getString(7)==null?"":rset.getString(7))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"30\"><font size=\""+size_data+"\">"+(rset.getString(8)==null?"":rset.getString(8))+"</font></td>\n");
os.writeBytes("</tr>\n");
36
query=query+",'"+rset.getString(8)+"'";
}
os.writeBytes("</table>\n");
os.writeBytes("<P/>\n");
os.writeBytes("<br>\n");
if (notEOS) {
cont=1;
os.writeBytes("<P align=center>\n");
os.writeBytes("<table border align=\"center\" cellspacing=\"0\"
cellpadding=\"6\" bordercolor=\"Black\" width=\"100%\">\n");
THVDR_List(comm,os);
os.writeBytes("</tr>\n");
os.writeBytes("<tr align=\"left\" valign=\"top\">\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"60\"><font size=\""+size_data+"\">"+(rset.getString(1)==null?"":rset.getString(1))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"280\"><font
size=\""+size_data+"\">"+(rset.getString(2)==null?"-":rset.getString(2))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"100\"><font
size=\""+size_data+"\">"+(rset.getString(3)==null?"-":rset.getString(3))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"100\"><font
size=\""+size_data+"\">"+(rset.getString(4)==null?"-":rset.getString(4))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
37
height=\""+height+"\" width=\"100\"><font
size=\""+size_data+"\">"+(rset.getString(5)==null?"-":((String)
ci_doc.get(rset.getString(5))))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"50\"><font size=\""+size_data+"\">"+(rset.getString(6)==null?"":rset.getString(6))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"70\"><font size=\""+size_data+"\">"+(rset.getString(7)==null?"":rset.getString(7))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\" width=\"30\"><font size=\""+size_data+"\">"+(rset.getString(8)==null?"":rset.getString(8))+"</font></td>\n");
os.writeBytes("</tr>\n");
query=query+",'"+rset.getString(8)+"'";
}
} while (notEOS);
query=query+") order by cod_not";
origine=2*righe_primapagina1;
cont=cont % righe_primapagina1;
if (cont==0)
origine=0;
for (int i=1;i<=(origine-cont*2);i++)
os.writeBytes("<br>\n");
rset=conect.Search(query);
38
os.writeBytes("<P align=center>\n");
os.writeBytes("<table border align=\"center\" cellspacing=\"0\"
cellpadding=\"6\" bordercolor=\"Black\" width=\"100%\">\n");
THVDR_Note(comm,os);
cont=0;
do {
while ((notEOS=rset.next()) &&
(cont<righe_primapagina2)) {
cont++;
os.writeBytes("<tr align=\"left\"
valign=\"top\">\n");
os.writeBytes("<td rowspan=1 colspan=1
width=\"20%\" height=\""+height+"\"><font
size=\""+size_data+"\">"+(rset.getString(1)==null?"-":rset.getString(1))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\"><font size=\""+size_data+"\">"+(rset.getString(2)==null?"":rset.getString(2))+"</font></td>\n");
os.writeBytes("</tr>\n");
}
os.writeBytes("</table>\n");
os.writeBytes("<P/>\n");
os.writeBytes("<br>\n");
if (notEOS) {
cont=1;
os.writeBytes("<P align=center>\n");
os.writeBytes("<table border align=\"center\" cellspacing=\"0\"
39
cellpadding=\"6\" bordercolor=\"Black\" width=\"100%\">\n");
THVDR_Note(comm,os);
os.writeBytes("<tr align=\"left\"
valign=\"top\">\n");
os.writeBytes("<td rowspan=1 colspan=1
width=\"20%\" height=\""+height+"\"><font
size=\""+size_data+"\">"+(rset.getString(1)==null?"-":rset.getString(1))+"</font></td>\n");
os.writeBytes("<td rowspan=1 colspan=1
height=\""+height+"\"><font size=\""+size_data+"\">"+(rset.getString(2)==null?"":rset.getString(2))+"</font></td>\n");
os.writeBytes("</tr>\n");
}
} while (notEOS);
os.writeBytes("</body>\n");
os.writeBytes("</html>");
os.writeByte('\n');
os.writeBytes("FINE");
os.writeByte('\n');
if ((st=is.readLine()) != null) {
System.out.println(st);
app.getAppletContext().showDocument(new
URL("http://vdr/"+st),"report");
}
}
os.close();
40
is.close();
channel.close();
41
import java.awt.*;
import java.io.*;
import java.net.*;
public class SimpleServer {
public static void main(String[] args) {
Socket channel;
DataInputStream in;
DataOutputStream out;
ServerSocket server;
boolean listening=true;
String st,ind,path;
OutputStream fi;
int cont,port;
try {
port=22500;
if (1<=args.length)
port=Integer.parseInt(args[0]);
path="";
if (2<=args.length)
path=args[1];
server = new ServerSocket(port, 15);
ind="0";
cont=0;
42
while (listening) {
channel = server.accept();
out = new DataOutputStream(channel.getOutputStream());
in = new DataInputStream(channel.getInputStream());
if ((ind=in.readLine()) != null) {
cont++;
fi = new
FileOutputStream("/u04/vdradm/web/doc/"+path+"file"+String.valueOf(cont)+".html");
while (((st=in.readLine()) != null) && (st.compareTo("FINE")!=0)) {
byte buffer[]=new byte[st.length()];
for (int i=0;i<buffer.length;i++)
buffer[i]=(byte) st.charAt(i);
fi.write(buffer);
fi.write((byte) '\n');
}
fi.close();
}
out.writeBytes(path+"file"+String.valueOf(cont)+".html");
out.writeByte('\n');
out.close();
in.close();
}
} catch (IOException e) {
System.err.println("I/O failed on the connection to: rs3edp "+e);
}
}
43
Appendice B
Il Calcolo della Riscrittura di Termini
L'uso dei paradigmi di programmazione logica e funzionale, e più in generale
dei linguaggi dichiarativi, come supporto per la definizione di un linguaggio di
programmazione ha trovato negli ultimi 30 anni sempre maggior spazio fra le
attività di ricerca. A differenza dei più comuni linguaggi di programmazione
tradizionali (FORTRAN, Pascal, C), che sono basati sul paradigma imperativo, i
linguaggi logici (generalmente linguaggi della Logica dei Predicati del Primo
Ordine) adottano un modello dichiarativo di rappresentazione della realtà. Un
programma scritto in un linguaggio di programmazione tradizionale consiste in una
sequenza di istruzioni che specificano in modo estremamente dettagliato le
operazioni necessarie per risolvere un dato problema; un linguaggio logico, invece,
descrive astrattamente un dato problema attraverso un insieme di formule ben
formate, senza precisare in modo particolareggiato una qualche procedura di
calcolo per la sua risoluzione. In altre parole, un programma scritto in un
linguaggio logico fornisce solamente la specifica dichiarativa di un dato problema,
lasciando ad un suo esecutore la preoccupazione di provvedere al meccanismo di
risoluzione, ovvero al motore inferenziale.
I progressi ottenuti in questo campo, con la definizione del primo linguaggio di
Programmazione Logica (PROLOG), hanno stimolato la ricerca sulle possibilità di
adottare i linguaggi logici, e più in generale i linguaggi dichiarativi, come linguaggi
44
macchina per nuovi elaboratori; in particolare, i linguaggi dichiarativi sembrano
offrire maggiori prestazioni rispetto ai linguaggi imperativi tradizionali nella
progettazione di macchine parallele, combinando efficienza a livello hardware e
facilità di programmazione a livello software.
Le architetture parallele dell'attuale generazione sono caratterizzate da 3
operazioni fondamentali, in base alle quali possono essere classificate:
•
assegnamento dei lavori ai processori disponibili, che possono lavorare in
parallelo;
•
comunicazione fra i vari processori;
•
controllo dell'esecuzione di un lavoro.
La cosiddetta granularità rappresenta la dimensione dei lavori assegnati ai vari
processori: il parallelismo a grana fine utilizza lavori di dimensioni molto piccole
(spesso una singola istruzione), che necessitano di modificare costantemente i
dati, mentre il parallelismo a grana grossa usa lavori dimensionalmente ampi che
raramente hanno bisogno di cambiare i dati. Le architetture a grana fine sono
tipicamente costituite da molti elementi opportunamente collegati, e per questo
richiedono un'efficiente comunicazione fra i vari processori: generalmente i vari
processori possono modificare direttamente i dati, come in una struttura Pipeline o
in systolic arrays, muovendo i dati lungo percorsi prestabiliti. Le architetture a
grana grossa, invece, prevedono raramente il trasferimento dei dati e possono,
perciò, essere realizzate anche con risorse per la comunicazione tipicamente
responsabili del cosiddetto "collo di bottiglia di Von Neumann", come memorie
condivise, buses, e reti. Osserviamo, infine, che il controllo dell'esecuzione di un
lavoro può essere o centralizzato (SIMD, Single Instruction stream, Multiple Data
stream), con un'unità di controllo che comunica le stesse istruzioni a tutti i
processori, oppure distribuito (MIMD, Multiple Instruction stream, Multiple Data
stream), dove ogni processore esegue la propria sequenza di istruzioni sui propri
45
dati. Le macchine a grana fine supportano il parallelismo SIMD, mentre quelle a
grana grossa supportano il parallelismo MIMD.
L'esperienza mostra che esistono problemi localmente omogenei, per i quali
cioè
più
istanze
di
una
singola
istruzione
possono
essere
applicate
simultaneamente a più parti di uno stesso dato (adatti ad un parallelismo SIMD), e
problemi globalmente inomogenei, composti da sottoproblemi differenti con poche
caratteristiche in comune (adatti ad un parallelismo MIMD). Per tale classe di
problemi la soluzione ottimale è rappresentata da macchine a multi-grana, che
gestiscono in modo MIMD più processori, ognuno dei quali lavora in modo SIMD
indipendentemente dagli altri.
Il maggior ostacolo per un effettivo uso delle macchine parallele è
rappresentato dalla difficoltà di una loro programmazione: esiste, infatti, un vuoto
("gap") fra le macchine parallele e i linguaggi di programmazione ad alto livello.
Fra gli attuali modelli di calcolo quelli alla Von Neumann e i relativi linguaggi
imperativi non possono efficientemente supportare il parallelismo, in quanto sono
inerentemente sequenziali: i programmi scritti in linguaggi imperativi paralleli sono
difficili da comprendere e mettere a punto, e sono legati alle risorse hardware
disponibili. I modelli di calcolo dichiarativi, invece, presentano il vantaggio di non
richiedere ordini specifici di esecuzioni per rendere esplicito il loro parallelismo, e i
programmi scritti nei relativi linguaggi dichiarativi sono facilmente trasportabili, in
quanto indipendenti dalle risorse hardware disponibili.
In questo contesto, particolarmente importanti sono gli studi sul Calcolo della
Riscrittura di termini: da una parte, infatti, il Calcolo della Riscrittura gioca un
ruolo
storicamente
fondamentale
nella
formalizzazione
della
nozione
di
computabilità, essendo equivalente alle Macchine di Turing, agli Algoritmi di
Markov, ecc..., dall'altra offre la possibilità di realizzare più modelli di calcolo in
parallelo. Intuitivamente, il Calcolo della Riscrittura appare come una restrizione
46
del Calcolo del Rimpiazzamento di Eguali con Eguali: in tale Teoria si definisce una
regola di inferenza, detta riscrittura, che permette la sostituzione "unidirezionale"
di termini sintatticamente diversi, ma semanticamente uguali.
La progettazione di una macchina dedicata al Calcolo della Riscrittura richiede lo
sviluppo di nuovi modelli di esecuzione, in generali più complicati di quelli che
supportano i linguaggi imperativi: in particolare, per esempio, viene abbandonato
il concetto tradizionale di "memoria", e l'operazione fondamentale dei linguaggi
imperativi, cioè l'assegnamento o memorizzazione, viene sostituita dalla relazione
di matching. Da una parte si confida nella possibilità di superare il collo di bottiglia
di Von Neumann, tipico dei sistemi di calcolo tradizionali, eliminando la
separazione fisica fra processori e memoria, e quindi la condivisione delle "risorse
per la comunicazione", responsabili di code di richieste di comunicazione fra le
varie unità di un calcolatore: l'idea chiave è pensare ad un'elaborazione locale dei
dati, ovvero ad un'elaborazione dei dati esattamente dove sono memorizzati.
Dall'altra l'eliminazione di programmi di interfaccia, quali interpreti e traduttori,
può realizzare l'idea di una macchina capace di "eseguire" direttamente programmi
ad alto livello.
Il Calcolo della Riscrittura presenta 4 modelli di computazione dichiarativi:
•
la Riscrittura Concorrente, che permette l'applicazione contemporanea di più
regole in più parti di un dato;
•
la Riscrittura Parallela, che consente l'applicazione simultanea di una singola
regola in più parti di un dato;
•
la Riscrittura Sequenziale, che applica una regola per volta in una singola parte
di un dato;
•
la Riscrittura Parallela Partizionata (Associativa), che suddivide un dato in un
certo numero di dominii omogenei su ognuno dei quali è realizzata la
Riscrittura Parallela generalmente con regole differenti per ogni differente
47
dominio.
La Riscrittura Concorrente potrebbe essere realizzata attraverso un'architettura
MIMD, mentre la Riscrittura Parallela attraverso un'architettura SIMD; la Riscrittura
Sequenziale corrisponde al tradizionale modello di calcolo di Von Neumann, e la
Riscrittura Parallela Partizionata presenta un parallelismo SIMD a livello locale, e
un parallelismo MIMD a livello globale, e quindi un parallelismo nel complesso
multi-grana.
In un precedente lavoro abbiamo presentato un'architettura di una macchina
per l'implementazione del Calcolo della Riscrittura: la Macchina a Riduzione, o
Reduction Machine (RM). Ricollegandoci a precedenti studi sulla definizione di
macchine per l'unificazione in parallelo, abbiamo descritto una Macchina che
realizza secondo una tecnica associativa la riduzione di un termine in forma
normale rispetto ad un sistema di riscrittura terminante, confluente, e lineare a
sinistra e a destra.
Il progetto della Reduction Machine estende, attraverso un'architettura a
Pipeline o systolic arrays, nella quale i dati si muovono lungo percorsi prestabiliti,
la potenziale efficienza del parallelismo a grana fine a computazioni globalmente
inomogenee, partizionando dinamicamente i dati in dominii omogenei, ognuno dei
quali può essere elaborato all'interno di un singolo blocco Rule.
48
Bibliografia
[1]
Cerabolini L. (1995), “Le reti”, Jackson Libri S.r.l.
[2]
Ghislandi P., Esposito A., Pozzoli G. (1996), “Didattica a distanza. Il
progetto MOEBIUS, sociologia on-line all’Università di Milano”, CTU NotizieUniversità degli Studi di Milano.
[3]
Lemay L. (1997), “HTML 3.2”, McGraw-Hill Libri Italia S.r.l.
[4]
Margarita S. (1996), “Un’esperienza di formazione multimediale: Multimedia
Mathematics”, atti del Convegno “Rota ‘96-La formazione e il lavoro al tempo delle
reti telematiche”, Torino , 23 novembre 1996.
[5]
[6]
Naughton P. (1996), “Il manuale Java”, McGraw-Hill Libri Italia S.r.l.
Schank J. D. (1996), “Il manuale Client/Server. Architettura e Applicazioni”,
McGraw-Hill Libri Italia S.r.l.
49
50