Newsgroup: it.comp.java
Titolo: Mistero di java e socket

Premetto che sto utilizzando l'untima sdk java stabile e l'ultimo kernel
Linux.
Devo sviluppare un'applicazione, la quale ha buona probabilità di perdere
la connessione di rete con un server a cui è collegato con una
comunicazione TCP/IP.
Stranamente, le write e i flush che opero NON sono bloccanti, come invece
è riportato nella documentazione. Ciò causa la perdita dei dati inviati,
visto che non ricevo le IOException aspettate.
Questa è una classe di esempio (sostituite l'host con uno a vostra scelta):
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class SocketDisconnectionTest {
	public static void main(String[] args) {
		Socket socket;
 
		try {
			socket = new Socket(InetAddress.getByName("192.168.1.253"), 59000);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
		try {
		System.out.println("Please unplug your cable");
		String test = "test1\n";
		OutputStream out = socket.getOutputStream();
		out.write(test.getBytes());
		out.flush();
		Thread.sleep(10000);
		out.write(test.getBytes());
		out.flush();
		out.close();
		}
		catch (Exception e) {
			System.out.println("Error detected");
			return;
		}
 
		System.out.println("Error NOT detected");
 
 
	}
}
Se eseguo il programma e tolgo il cavo di rete nei 10 secondi di attesa,
il programma al suo risveglio invia i dati, chiama flush e chiude la
connessione come se i dati fossero stati inviati correttamente.
Dubito che sia il comportamento corretto...
Credete sia il caso di segnalare il bug, è un comportamenteo documentato o
sto sbagliando io?
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 sto sbagliando io?
Per quanto riguarda la perdita di dati, non sono sicuro al 100% che la 
mia risposta sia esatta, ma suppongo che sia il comportamento corretto. 
Questa ipotesi la supporto dalla javadoc per il metodo flush() su 
OutputStream:
"If the intended destination of this stream is an abstraction provided 
by the underlying operating system, for example a file, then flushing 
the stream guarantees only that bytes previously written to the stream 
are passed to the operating system for writing; it does not guarantee 
that they are actually written to a physical device such as a disk 
drive."
Non specifica nulla riguardo al comporamento con i socket, ma se 
funziona allo stesso modo che con i file, java si occupa soltanto di (e 
suppone che la flush() sia andata a buon fine) quando riesce a passare 
i dati al sistema operativo, che si occupa poi di inviarli 
effettivamente. Detto questo, potresti provare ad aumentare il delay 
tra una trasmissione e l'altra, in modo che il SO rilevi la 
disconnessione dalla rete e nel momento in cui il programma tenta di 
inviare dei dati verso una stazione remota, il SO rifiuti la presa in 
carico della trasmissione.
Spero di non aver sparato troppe cavolate e di essere stato utile! :)
Ciao,
Elvandar

 Spero di non aver sparato troppe cavolate e di essere stato utile! :)
Sei stato utilizzimo, anche se è stata una conferma di ciò che pensavo
(putroppo).
:) :)




Hai mai provato a guardare tra le opzioni TCP?
   socket.setKeepAlive(boolean)
se true, manda segnali periodici -non ricordo quanto- sul socket aperto
(invisibili alla tua applicazione e all'applicazione collegata) per
controllare se la connettività è presente o no. Se l'altra parte non
risponde, al primo tentativo di comunicazione ti becchi un'eccezione
   socket.setSoLinger(boolean, int)
se true, prima di chiudere il socket il sistema operativo tenta di mandare
comunque i dati in buffer, utilizzando un timeout (millisecondi) specificato
come secondo parametro
   socket.setSendBufferSize(int)
misurato in byte, se è abbastanza piccolo... indovina? nota: è solo un
suggerimento per il sistema operativo, che se ne può anche fregare.
   socket.setTcpNoDelay(boolean)
se true, disabilita l'algoritmo di Nagle. Leggi qua per una spiegazione
semplice semplice:
http://telemat.die.unifi.it/book/1997/winsock_prg/wsk_doc3.html#TCP_NODELAY
pare faccia al caso tuo, no? nota: questo non è un suggerimento per il
sistema operativo, se hai bisogno di disabilitare l'algoritmo di Nagle il
layer sottostante lo fa e basta, Linux o Windows che sia.
Insomma, se ci sono persone che con Java hanno anche sviluppato applicazioni
VOIP, un motivo ci sarà...
In bocca al lupo!
-- 
Scientology: se la conosci la eviti, se la conosci non ti uccide...
http://xenu.com-it.net
 - 
http://xenu.freewinds.cx/
 - 
http://www.xenu.net/
(per rispondere personalmente leva IlDitoDalCulo)
http://www.webalice.it/ech3l0n/HastaLaVictoria.jpg
   -   Siempre!

 In bocca al lupo!
Crepi :) (anche se è già bello che morto il lupo) :)


 
-- 
----------------------------------------------------------------------------------
       /)/)		La mia vita è tutta rose e fiori...
      ( '.')
    o(('')('')				... ma io sono allergico !!!