Newsgroup: it.comp.java
Titolo: [java.net] cicli di attesa...

Volevo sviluppare un programmino che mi facesse da tunnel HTTP per bypassare
il proxy attraverso l'ausilio di un server web (mycgiserver?), così ho
cominciato a giocare con le API di java.net.*
Premetto che sono un completo ignorante in materia di 
java.net
, se non per
qualche barlume di nozione quà e là... così stamattina (essendo tutti in
vacanza) ho provato a fare una classe di prova (a dir la verità era un
TestCase che avrebbe dovuto guidarmi nello sviluppo del server locale per il
tunneling), che però mi sta facendo sorgere una serie di dubbi.
Spero che qualche esperto sappia darmi qualche indicazione.
La classe prova è composta di una static inner class che non è altro che un
Server che ascolta sulla porta 8080. I metodi esposti sono "start()" e
"stop()" come ogni 'server' dovrebbe fare :-). Il server riceve una
connessione legge i dati inviati dal client e risponde con gli stessi dati
appendendo " it works!".
La parte client è un main statico che si connette al server spedisce dei
dati e si aspetta di ricevere in risposta la stringa inviata con 'appesa' la
stringa "it works".
Questa classe presa ed eseguita funziona... ma il problema è che ho dovuto
inserire quì e là dei blocchi di attesa in corrispondenza dei commenti, che
pongono gli interrogativi... se li tolgo rischio che il server non riceva i
dati, o che ci siano eccezioni (provate voi stessi).
Ecco dove ho dovuto inserire i cicli di attesa:
Il server subito dopo aver ricevuto la connessione si deve mettere in attesa
che il client gli spedisca i dati...
Dopo che il client ha spedito i dati si deve mettere in attesa che il server
abbia ricevuto i dati...
Quindi il server legge i dati, spedisce la risposta e prima di chiudere il
socket si mette in attesa che il client abbia finito di leggere la
risposta...
Ora i miei dubbi sono... io ho messo 100 millisecondi di attesa, che se
tolti mandano il programma in errore (!!!).
Ma come faccio io a indovinare se questa attesa è sufficiente? Io ero
convinto che l' IO bloccasse l'esecuzione e che quindi non ci fosse bisogno
di questi cicli di attesa!!! Ora questo programmino è stupido e banale, ma
se la complessità cresce, come si gestiscono queste cose? Sono convinto che
esistano dei "pattern" di utilizzo delle classi di 
java.net
.
(confesso che mi vergogno di non sapere nulla di 
java.net
)
Qualcuno mi illumina per favore?
Luigi
import java.io.*;
import java.net.*;
public class Prova {
    //-- Server
    static class Server {
        private ServerSocket ss;
        private int listenPort;
        private boolean running = false;
        private boolean waiting = false;
        Server(int listenPort) {
            this.listenPort = listenPort;
        }
        public synchronized boolean isRunning() {
            return running;
        }
        public synchronized void setRunning(boolean running) {
            this.running = running;
        }
        public void start() {
            System.out.println("[server] Starting server ");
            if (isRunning()) {
                throw new IllegalStateException(
                        getClass().getName() + " already running!");
            }
            setRunning(true);
            Thread serverThread = new Thread() {
                public void run() {
                    try {
                        ss = new ServerSocket(listenPort);
                        while (isRunning()) {
                            waiting = true;
                            //System.out.println("[server] Listening ");
                            Socket s = ss.accept();
                            waiting = false;
                            System.out.println("[server] Connection from " +
s);
                            // Domanda: come faccio a sapere quando il
client è
                            // pronto per inviare i dati?
                            try {
                                sleep(100);
                            }
                            catch (InterruptedException ex) {
                            }
                            try {
                                InputStream is = s.getInputStream();
                                byte[] bytes = new byte[is.available()];
                                is.read(bytes);
                                String data = new String(bytes);
                                System.out.println("[server] Data received:
" +
                                        "<" + data + ">");
                                String response = data + " it works!";
                                System.out.println(
                                        "[server] Sending response: " +
                                        response);
                                OutputStream os = s.getOutputStream();
                                os.write(response.getBytes());
                                os.flush();
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                            // Domanda: come faccio a sapere quando il
client ha
                            // finito di leggere la risposta?
                            try {
                                sleep(100);
                            }
                            catch (InterruptedException ex) {
                            }
                            s.close();
                        }
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    } finally {
                        try {
                            ss.close();
                            System.out.println("[server] Server stopped");
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                        setRunning(false);
                    }
                }
            };
            serverThread.setDaemon(false);
            serverThread.start();
            waitUntilStarted();
            System.out.println("[server] Server started");
        }
        /**
         * Ciclo di attesa per dare il tempo al server di mettersi
         * in listening...
         */
        private void waitUntilStarted() {
            try {
                while (! waiting) {
                    Thread.sleep(100);
                }
                Thread.sleep(100);
            }
            catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        public void stop() {
            System.out.println("[server] Shutting down server ");
            if (! isRunning()) {
                return;
            }
            setRunning(false); // imposta il flag di fine del thread
            try {
                if (waiting) { // sblocca il thread se è in fase di
listening
                    Socket s = new Socket(InetAddress.getLocalHost(),
                            listenPort);
                    s.close();
                }
            }
            catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    //--- client
    private static Server server = null;
    private static  int SERVER_PORT = 8080;
    private static  String SERVER_HOST = "localhost";
    public static void main(String[] args) throws Exception {
        startServer();
        System.out.println("[client] Connecting to " + SERVER_HOST +
                           ":" + SERVER_PORT);
        Socket socket = new Socket(SERVER_HOST, SERVER_PORT);
        System.out.println("[client] Connected: " + socket);
        OutputStream os = socket.getOutputStream();
        // Spedisce il messaggio
        String data = "messaggio";
        System.out.println("[client] Sending " + data);
        os.write(data.getBytes());
        os.flush();
        Thread.sleep(100); // perché se lo tolgo non funziona?
        InputStream is = socket.getInputStream();
        // Riceve il messaggio
        byte[] bytes = new byte[is.available()];
        is.read(bytes);
        String received = new String(bytes);
        socket.close();
        String expected = data + " it works!";
        if (expected.equals(received)) {
            System.out.println("[client] tutto funziona...");
        } else {
            System.out.println(
                    "[client] non funziona," +
                    ": expected <" + expected  +
                    "> received <" + received +">");
        }
        stopServer();
    }
    private static void startServer() {
        server = new Server(SERVER_PORT);
        server.start();
    }
    private static void stopServer() {
        server.stop();
    }
}

                                System.out.println("[server] Data received:
mi sono fermato a leggere qui. innanzi tutto invece di usare gli stream
grezzi potresti farti aiutare da qualche classe che, in omaggio, ti dia
anche un po' piu' di efficienza (buffered). questa tecnica appare nel
tutorial sun.
out = new PrintWriter(sock.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
ovviamente controlla se le classi che ho portato ad esempio fanno al
caso tuo; queste si adattano bene all'i/o a linee. ce ne sono altre
comunque pero' almeno la Buffered* direi che sia d'obbligo...
tornando al tuo codice l'errore si capisce andandosi a leggere la
documentazione di InputStream:
byte[] bytes = new byte[is.available()];
is.read(bytes);
supponiamo che is.available() ritorni 0 (il client non ha spedito ancora
nulla). allora read non blocca e ritorna 0 perche' gli hai fornito un
array di lunghezza 0, ovvero non vuoi leggere nulla.
non ho controllato tutto il codice che hai fornito ma se hai usato
sempre la stessa tecnica...
ciao
-- 
Seti@Home Java Applets
http://maruko.cjb.net/

 Qualcuno mi illumina per favore?
Prima cosa, l'architettura di un server prevede normalmente che il client 
sia gestito da un thread separato: passi la socket ritornata dall'accept ad 
un thread apposito che poi fai partire, mentre la serversocket torna subito 
in accept sul thread principale. In altri contesti si fa coi processi.
Secondo, avere client e server nello stesso programma e' probabilmente la 
causa del tuo problema - dato che ti trovi a dover gestire la coordinazione 
interthread di thread che invece in una situazione normale sono del tutto 
indipendenti (e la cosa, visto il modello di threading di java, dipende da 
come la JVM e/o il s/o sottostante implementano il thread scheduling - ed 
eccoti i tuoi ritardi).
Insomma il tuo esempio e' fuorviante - scrivi due classi separate, una per 
il server, una per il client, e non ti serviranno ritardi di sorta.
-- 
Life's something u don't get out alive..
ObjectZone - 
http://space.tin.it/computer/csadun

 il server, una per il client, e non ti serviranno ritardi di sorta.
Ok, provvedo, ma il problema (mi sembra) č lo stesso.
Riorganizzo il codice e ci riprovo :-)
TNX
Jigi

Rifattorizzato, ora è senz'altro un po' più leggibile :-). Il problema però
persiste. Sul client ho dovuto aumentare lo sleep per evitare l'errore
(ovvero il server non riceve nulla, e il test fallisce)
Grazie Cristiano :-)
Luigi
import java.io.*;
import java.net.*;
public class Client {
    //--- client
    private static Server server = null;
    private static  int SERVER_PORT = 8080;
    private static  String SERVER_HOST = "localhost";
    public static void main(String[] args) throws Exception {
        startServer();
        System.out.println("[client] Connecting to "
                           + SERVER_HOST + ":" + SERVER_PORT);
        Socket socket = new Socket(SERVER_HOST, SERVER_PORT);
        System.out.println("[client] Connected: " + socket);
        OutputStream os = socket.getOutputStream();
        // Spedisce il messaggio
        String data = "messaggio";
        System.out.println("[client] Sending " + data);
        os.write(data.getBytes());
        os.flush();
        Thread.sleep(1000); // perché se lo tolgo non funziona?
        InputStream is = socket.getInputStream();
        // Riceve il messaggio
        byte[] bytes = new byte[is.available()];
        is.read(bytes);
        String received = new String(bytes);
        socket.close();
        String expected = data + " it works!";
        if (expected.equals(received)) {
            System.out.println("[client] tutto funziona...");
        } else {
            System.out.println(
                    "[client] non funziona, "+
                    "expected <"+ expected +
                    "> received <"+ received+">");
        }
        stopServer();
    }
    private static void startServer() {
        server = new Server(SERVER_PORT);
        server.start();
    }
    private static void stopServer() {
        server.stop();
    }
}
import java.net.*;
import java.io.*;
public class Server {






                        // parte il thread dedicato al client
                        new SocketHandler(s);




    /**[delete-me]/
    public static void main(String[] args) throws Exception {
        TestWebServer tws = new TestWebServer(8080);
        tws.start();
        System.out.println("Press [enter] to shutdown the webserver");
        readLine();
        tws.stop();
    }
    private static void readLine() throws IOException {
        BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
        br.readLine();
    }
    /**/
}
import java.net.*;
import java.io.*;
public class SocketHandler extends Thread {
    private Socket s;
    public SocketHandler(Socket socket) {
        this.s = socket;
        start();
    }
    public void run() {
        // Domanda: come faccio a sapere quando il client è
        // pronto per inviare i dati?
        try {
            sleep(100);
        }
        catch (InterruptedException ex) {
        }
        try {
            InputStream is = s.getInputStream();
            byte[] bytes = new byte[is.available()];
            is.read(bytes);
            String data = new String(bytes);
            System.out.println("[server] Data received: " +
                               "<" + data + ">");
            String response = data + " it works!";
            System.out.println(
                    "[server] Sending response: " +
                    response);
            OutputStream os = s.getOutputStream();
            os.write(response.getBytes());
            os.flush();
            s.close();


 il proxy attraverso l'ausilio di un server web (mycgiserver?)
Scusa, non capisco lo scopo... hai un programma scritto in Java che deve uscire
attraverso un proxy? Nel caso puoi settare la JVM per usare il proxy e ti eviti
un sacco di lavoro. Vuoi uscire all'esterno da una rete aziendale chiusa?
Cos'altro? Non vorrei che tu stessi reinventando la ruota... mi illumini?
Ciao,
 Stefano
----------
"X WindowSSS, teSSSoro mio... lo odieremo per SSSempre"
Bill Gollum
----------

Forse intendevi che il client non dovrebbe lanciare il server. Ho provato
anche questo.
Ora noto che nel SocketHandler non è più necessario nessuno sleep. Però sul
client, se tolgo lo sleep mi va in errore... perché ?
Grazie dinuovo.
Luigi
import java.io.*;
import java.net.*;
public class Client {
    //--- client
    private static Server server = null;
    private static  int SERVER_PORT = 8080;
    private static  String SERVER_HOST = "localhost";
    public static void main(String[] args) throws Exception {
//        startServer();
        System.out.println("[client] Connecting to "
                           + SERVER_HOST + ":" + SERVER_PORT);
        Socket socket = new Socket(SERVER_HOST, SERVER_PORT);
        System.out.println("[client] Connected: " + socket);
        OutputStream os = socket.getOutputStream();
        // Spedisce il messaggio
        String data = "messaggio";
        System.out.println("[client] Sending " + data);
        os.write(data.getBytes());
        os.flush();
        Thread.sleep(300); // perché se lo tolgo non funziona?
        InputStream is = socket.getInputStream();
        // Riceve il messaggio
        byte[] bytes = new byte[is.available()];
        is.read(bytes);
        String received = new String(bytes);
        socket.close();
        String expected = data + " it works!";
        if (expected.equals(received)) {
            System.out.println("[client] tutto funziona...");
        } else {
            System.out.println(
                    "[client] non funziona, "+
                    "expected <"+ expected +
                    "> received <"+ received+">");
        }
//        stopServer();
    }
//    private static void startServer() {
//        server = new Server(SERVER_PORT);
//        server.start();
//    }
//    private static void stopServer() {
//        server.stop();
//    }
}
import java.net.*;
import java.io.*;










    /**/
    public static void main(String[] args) throws Exception {
        Server tws = new Server(8080);
        tws.start();
        System.out.println("Press [enter] to shutdown the webserver");
        readLine();
        tws.stop();
    }
    private static void readLine() throws IOException {
        BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
        br.readLine();
    }
    /**/
}
import java.net.*;
import java.io.*;
public class SocketHandler extends Thread {
    private Socket s;
    public SocketHandler(Socket socket) {
        this.s = socket;
        start();
    }
    public void run() {



Il proxy mi permette l'uscita solo su porta HTTP.
Metti che io devo accedere a 
ftp://xyz
 ma sono dietro un firewall che mi
permette di uscire solo via HTTP.
Dico al mio client FTP di collegarsi a 
ftp://localhost
sul mio pc gira un server che accetta richieste sulla porta FTP. Questo
serverino locale apre un URL WEB su un webserver remoto che può connettersi
ad 
ftp://xyz
 senza problemi, aprirò un URL del tipo
http://proxyremoto/tunnel?remoteHost=xyz&port=21
. Il web server in questo
modo capisce che deve connettersi con xyz:21, e girare gli stream al mio
serverino in locale. Il proxy non mi blocca perché mi sto connettendo ad una
risorsa web.
A questo punto il server in locale, anche lui, non fa altro che fare da
proxy permettendo ad IE di colloquiare con 
ftp://xyz
 passando attraverso un
firewall e un proxy HTTP.
E' un po' un casino, e spero di non aver detto fesserie :-) Questo giro
comunque dovrebbe chiamarsi HTTP-Tunneling, e mi piacerebbe implementarlo in
Java.
Luigi

 implementarlo in Java
No, no sono fesserie - se pero' ti interessa oltre l'esercizio mi pare ci 
sia gia' un bel po' di roba gia' fatta, in Java e no.


Spero che qualche esperto sappia darmi qualche indicazione.
[CUT]
Mi sono buttato a leggere il tuo codice e vedere cosa potevo fare, ma 
poi mi sono detto "perché reinventare la ruota (magari non troppo 
rotonda)?" :-)
C'è un bel capitoletto del Tutorial che penso faccia proprio al caso 
tuo (con tanto di esempi).
http://java.sun.com/docs/books/tutorial/networking/sockets/index.html
HTH
-- 
Ciao
	Fabrizio C.

 provato anche questo.
Falli girare in due JVM separate. E' cosi' che si suppone che girino. :)


> Falli girare in due JVM separate. E' cosi' che si suppone che girino. :)
L'ho fatto proprio con l'ultimo codice postato, ma se non metto la sleep sul
client, il server non riceve nulla.

Mi sembra che, se lo faccio girare in due VM separate, tolti i cicli di
attesa, succedono 4 cose "a random":
1) il server non riceve il messaggio e il client riceve una risposta
sbagliata
2) il server riceve il messaggio ma il client non riceve una risposta vuota
3) il server chiude la connessione prima che il client abbia cominciato a
leggere la risposta e il client si becca un'eccezione.
4) ultima possivilità: grazie a una strana congiunzione astrale a volte
tutto funziona...
Sono un po' perplesso.
Non ho usato stream bufferizzati perché voglio farlo funzionare senza (prima
lo faccio funzionare, e poi casomai lo ottimizzo). Non penso che sono
obbligato a bufferizzare i dati per usare un socket.
Dato uno sguardo sul java tutorial di sun, o mi è sfuggito qualcosa o non ci
ho visto nulla che mi chiarifichi perché devo 'aspettare'... gli stream non
dovrebbero fermare l'esecuzione del thread corrente?
se ripristino lo sleep nel client tutto sembra funzionare (ma... sarà
affidabile?  io credo di no).
(confuso)
Luigi

 attesa, succedono 4 cose "a random":
Ok, allora devo dare un'occhiata piu' dettagliata al codice :-)
Per curiosita', su che piattaforma fai girare il tutto?


 ha scritto nel messaggio
news:Xns9269983263AFDcr...@130.133.1.4...


 Ciao
Guarda, ho provato a darci un'occhiata veloce. Non so che tipo di 
eccezione ti dia, pero' una cosa che ho notato e' che il tuo 
protocollo non definisce un punto di chiusura (in effetti, 
non hai un protocollo :) che permetta di sincronizzare server e 
client su come e dove chiudere la socket.
Ti faccio un esempio di client/server scritto in cinque minuti che 
accetta un protocollo fatto di due comandi: MSG <stringa> e QUIT e 
scritto secondo il modo "normale" in due classi. Ascolta sulla 9999 
per default. Dimmi se ti funziona.
Server1.java:
import java.io.*;
import java.net.*;
public class Server1 extends Thread {
 private int port;
 private boolean shutdown;
 public Server1(int port) {
    this.port=port;
    this.shutdown=false;
 }
 public void run()  {
    System.out.println("Init");
    try {
        ServerSocket ss = new ServerSocket(port);
        while(!shutdown) {
                System.out.println("Accepting");
                Socket s = ss.accept();
                new Handler(this, s).start();
        }
    } catch(IOException e) {
            e.printStackTrace();
            shutdown();
    }
 }
 public void shutdown() {
    shutdown=true;
    interrupt();
 }
 public static void main(String args[]) throws Exception {
    int port=9999;
    if (args.length>0)
        try {
            port=Integer.parseInt(args[0]);
        } catch(NumberFormatException e) {
            System.err.println("Server [<port number>] (default:9999)");
        }
    new Server1(port).start();
 }
}
// Gestisce un singolo client
class Handler extends Thread {
    private Server1 server;
    private Socket s;
    private boolean shutdown;
    public Handler(Server1 server, Socket s) {
        this.server=server;
        this.s=s;
        this.shutdown=false;
    }
    public void run() {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
            PrintWriter os = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
            while(!shutdown) {
                String line = reader.readLine();
                if ("QUIT".equals(line)) quit(os);
                else if (line.startsWith("MSG ")) msg(os, line.substring(3).trim());
                else System.err.println("Comando sconosciuto: \""+line+"\"");
            }
        } catch(IOException e) {
            e.printStackTrace();
            shutdown();
        }
    }
    public void shutdown() {
        shutdown=true;
    }
    private void quit(PrintWriter os) throws IOException {
        System.out.println("Client "+s.getInetAddress().getHostName()+" terminato");
        s.close();
        shutdown();
    }
    private void msg(PrintWriter os, String msg) throws IOException {
        System.out.println("Client "+s.getInetAddress().getHostName()+" manda un messaggio");
        os.println("OK");
        os.flush();
        System.out.println("Messaggio ricevuto: "+msg);
    }
}
--------------------------------------------------------------------------------------------
Client 1.java:
import java.io.*;
import java.net.*;
public class Client1 {
    public static void main(String args[]) throws Exception {
        int port=9999;
        if (args.length>0)
            try {
                port=Integer.parseInt(args[0]);
            } catch(NumberFormatException e) {
                System.err.println("Client [<port number>] (default:9999)");
            }
        Socket s = new Socket("localhost", port);
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
        BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
        pw.println("MSG CIAO");
        pw.flush();
        String result = reader.readLine();
        if (! "OK".equals(result)) System.err.println("Il server non funziona");
        pw.println("MSG MONDO");
        pw.flush();
        result = reader.readLine();
        if (! "OK".equals(result)) System.err.println("Il server non funziona");
        pw.println("QUIT");
        pw.flush();


cosě ho cominciato a giocare con le API di java.net.*
Mi č venuto uno spavento! Quando ho letto il titolo del tuo post ho
pensato: mammamia la Sun ha venduto Java al nemico :PP
--
Rhymes (rhy...@NOSPAMmyself.com)
http://www26.brinkster.com/rhymes
" avevo Halo, poi č arrivata la mia fidanzata ;-) "

 client su come e dove chiudere la socket.
Ho capito: devo sincronizzare la chiusura dei socket.
Però stavo pensando se il mio client è un "generico client" tipo un ftp
client o un browser o un telnet... la chiusura del socket sul server come
faccio ad intercettarla? Boh... penso che per fare il mio programmino di
tunneling HTTP devo approfondire con un buon libro :-/
In pratica devo prendere dati da un socket (di qualsiasi protocollo) girarli
verso un URL, quindi leggere da questo URL e scrivere indietro sul socket.
Questa era l'idea. Pensavo di usare due thread, per le due direzioni. Ma mi
sa che per questa cosa dovrò approfondire su un libro.
Ho visto che dentro Axis c'è un tcpmonitor che fa questo genere di lavoro
visualizzando a video il contenuto dei dati scambiati. Sinceramente però non
so se gestisce protocolli non testuali, o se li gestisce tutti.
Prendendo il codice di tcpmonitor vedo che è molto ingarbugliato (in una
classe son definite 4 o 5 classi, alcune si occupano sia delle connessioni,
sia della visualizzazione), ma magari con uno sguardo più attento riuscirò a
coglierne il senso completo.
Quello che mi stupiva però è che:
        InputStream is = socket.getInputStream();
        // Riceve il messaggio
        byte[] bytes = new byte[is.available()];
        is.read(bytes);
        String received = new String(bytes);
non si blocca aspettando che dall'altra parte qualcuno spedisca qualcosa.
Effettivamente però probabile che se il socket non ha ancora scritto niente
is.available() ritorna 0... e il codice prosegue :-(.
In qualche modo quindi le 'pause' facevano funzionare l'esempietto. Dò uno
sguardo a come lavora tcpmonitor di axis. E magari è ora di leggersi un
libro su java networking.
Grazie mille, sei stato gentilissimo (lo so che quando mi ci metto sono un
martello)
Luigi

LOL.
Le ultime notizie di mamma Sun erano circa delle "inchieste" di prestiti
esosi ai top manager
http://it.news.yahoo.com/020809/25/1wz2x.html
il che ha fatto perdere qualche punto in borsa alla società, ma ormai di
borsa ho rinunciato a capirci qualcosa. Forse è più facile che imparo a
scrivere un po' di codice 'funzionante' con Socket e URL...

 niente is.available() ritorna 0... e il codice prosegue :-(
Puoi provare con 
while(true) {
    	if (int b=is.isAvailable()) // invia ad un thread apposito
    	Thread.sleep(..poll interval..)
}
che fa busy waiting :( ma equilibrando l'intervallo di polling potrebbe 
andare.



se invece di allocare 
	buf[is.abvailable()] 
si alloca 
	buf[QUANTITA_FISSA] 
allora la in.read(buf...) non verra' mai eseguita con un array di
lunghezza 0 e diventera' bloccante. niente attesa attiva quindi.


 Java.
Tutto chiaro. Grazie per la spiegazione.





Averlo in Java sarebbe carino :-) Ne sto usando uno che però è scritto in C,
per poter scaricare la posta su un POP server, ma è lentissimo (server web
pubblico un po' sovraccarico) e non ci sono i sorgenti. Una volta capito il
giro però, sembra una sciocchezza da programmare, non è altro che un
leggi-scrivi, una specie di proxy. Intanto però mi sono già bloccato su una
sciocchezza come questa :-(
Luigi

esosi ai top manager
Boh io non mi sono mai interessato della Sun in quanto societą..


 sia gia' un bel po' di roba gia' fatta, in Java e no.
In Java non ho trovato niente. Nemmeno su sourceforge.