MokaByte Numero 18 - Aprile 1998

 
Un Client Telnet
in Java 
di

Roberto Piola

Un semplice programma per controllare un host remoto utilizzando il protocollo telnet  


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:

 
    import java.net.*;
    import java.io.*;
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:
class Copy_Out extends Thread{
    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);}
         }
    }
  }
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:
 
class telnet{
  /* 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);}
        }
    }
}
 
That's all, folks.
 

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 rivista web su Java

MokaByte ricerca nuovi collaboratori
Chi volesse mettersi in contatto con noi può farlo scrivendo a mokainfo@mokabyte.it