MokaByte
Numero 18 - Aprile 1998
|
|||
|
in Java |
||
|
|
||
Introduzione
Nei numeri precedenti
di MokaByte è stato pubblicato un server telnet per java; un client
telnet generico presenta però alcune particolarità che è
il caso di affrontare separatamente; tipicamente, non si puo' attendere
un protocollo fisso a "botta e risposta", ma occorre attendersi dati dal
server o dalla tastiera in un qualunque momento.
Purtroppo java non possiede l'utilissimo costrutto select() del C, che blocca il programma in attesa del primo input su di un insieme di descrittori di file, ed obbliga ad avere due threads separati per gestire la comunicazione nelle due direzioni: un thread si bloccherà sulla read della tastiera in attesa di caratteri da inviare al server, mentre un altro thread si bloccherà sulla read dal socket in attesa di caratteri da presentare allo schermo.
In questo articolo verrà presentato un semplice programma di esempio che implementa un client telnet, stabilendo una connessione con una data porta TCP di un server e ricopiando i dati da/a tale socket a/da System.out e System.in; manca ovviamente tutta la parte necessaria per gestire l'emulazione del terminale (tasti di cursore, ecc.), che avrebbe appesantito inutilmente l'esposizione; il programma è comunque completo ed utilizzabile per lo meno per provare i vari server.
Il programma
Innanzituttto,
bisogna includere le parti della java library per la gestione di io e socket:
Poi, la classe Copy_Out provvede a fornire un thread che copia, in un loop senza fine, lo standard nput su di un dato stream:
import java.net.*;
import java.io.*;
class Copy_Out extends Thread{La classe principale contiene l'altro thread, che copia i dati in direzione opposta; anche qui si ha un loop senza fine in cui si entra dopo aver inizializzato il thread Copy_Out:
OutputStream ostr;
/* il costruttore semplicemente memorizza lo stream in cui copiare */
Copy_Out(OutputStream s){
ostr=s;
}
/* la run contiene il loop senza fine */
public void run(){
while(true){
try{
/* la read si blocca, senza consumare cicli di CPU, se sullo stream non ci sono caratteri in attesa */
int i=System.in.read();
/* la flush garantisce che il carattere venga inoltrato senza indugi */
ostr.write(i);
ostr.flush();
}
catch(Exception e) {System.err.println("Exit for "+e); System.exit(0);}
}
}
}
class telnet{That's all, folks.
/* l'applicazione va lanciata con l'indirizzo del server come primo parametro ed il numero di porta come secondo */
static public void main(String[]args) {
Socket s=null;
OutputStream os=null;
InputStream is=null;
int ni;
boolean finito=false;
/* apre socket di tipo stream */
try{
s=new Socket(args[0],Integer.valueOf(args[1]).intValue(),true);
os=s.getOutputStream();
is=s.getInputStream();
}
catch(Exception e) {
System.err.println("Exception "+e+" while creating socket with "+args[0]+":"+args[1]);
System.exit(1);
}
System.out.println("Connected with "+s.getInetAddress().toString());
/* viene creato il thread asiliario */
Copy_Out o=new Copy_Out(os);
o.start();
/* anche qui c'e' un loop senza fine */
while(true){
try{
int i=is.read();
/* la read ritorna -1 se il server remoto ha chiuso la connessione */
if(i==-1){
System.err.println("Exit: remote has closed connection");
System.exit(0);
}
System.out.write(i); System.out.flush();
}
catch(Exception e){System.err.println("Exit for "+e); System.exit(0);}
}
}
}
Nota
Utilizzando
il jdk 1.1.5 su Sun Solaris, il programma non da' alcun problema; provandolo
con jdk 1.1.3 sotto Linux invece sono stati osservati strani blocchi, presumibilmente
dovuti a bug nella gestione del socket.
Roberto Piola sta ultimando il dottorato di ricerca in Informatica presso l'Univversità di Torino; collabora con la rivista Login e con vari Internet Provider (Internet House, Pinerolo Internetworking e Magellano). |
|
||
|
||
MokaByte ricerca
nuovi collaboratori
|
||
|