Newsgroup: it.comp.java
Titolo: Java & Socket...Address already in use: JVM_Bind

Salve,
Sono un novellino di java, che dopo aver passato un'esame di
fondamenti di informatica si è appassionato a questo linguaggio.
Per fare un po di esercizio ho screato due classi che trasferiscono un
file da un pc ad un'altro, (FileSender e File Receiver) e  funzionano
correttamente).
Esaltato da questo successo ho desico di estendere il mio programmino,
facendo si che trasferisse intere directory con il loro contenuto.
Questo programma è composto da due classe (DirSend e DirRec) che
richiamano, per ogni file,  le classi file Sender e File Receiver.
Il problema è che riesce solo il trasferimento del primo file, al
secondo FileReceiver mi dà l'errore 
java.net.BindException: Address already in use: JVM_Bind
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(Unknown Source)
        at java.net.ServerSocket.bind(Unknown Source)
        at java.net.ServerSocket.<init>(Unknown Source)
        at java.net.ServerSocket.<init>(Unknown Source)
        at FileReceiver.initializeSocket(FileReceiver.java:47 eccetera
eccetera
Spulciando nei post passati di questo newsgroup,  ho scoperto che è
consigliabile chiudere la connessione del client prima di quella del
server, ed ho provveduto a questo, facendo aspettare il server per
circa mezzo secondo, ma la situazione non è migliorata.
Ho letto anche di qualcose tipo "socket in stato di close_wait" ma non
ho ben capito di cosa si tratta...
Come devo chiudere la connessione perchè tutto funzioni anche al
"secondo giro"?
Ringrazio chi perderà un po del suo tempo a leggermi,
Saluti
Wakko kid

Be' quindi chiudi il socket dopo ogni file inviato.. Perche' non
inviarli sulla stessa connessione?

inviarli sulla stessa connessione?
Verissimo... ma aveva già impostato la classe più "interna" in questo
modo (apriva e chiudeva la connesione al suo interno) così, la classe
che la utilizzava trovava, per ogni file la connessione chiusa..
Cmq, siccome tutto questo lo sto facendo per "smanettare" il punto è
ora riuscier a capire bene 'sto problema della chiusura delle
connesisioni...
Allora, io sono riuscito a sistemare un po' la questione, alzando di
brutto il tempo che intercorre trala chiusura della connessione e la
sua riapertura... siamo a circa un secondo e mezzo!
Non c'è modo di capire / farsi dire da qualche funzione quando la
connessione è chiusa ed è possibile aprirne un'altra?
Saluti, Wakko Kid
X joao: Grazie di avermi risposto!

Ciao, sinceramente non so quanto tempo possa intercorrere tra
l'installazione di 2 ServerSocket sulla stessa porta. Questo tempo puo'
dipendere sia dalla JVM che non fa girare il GarbageCollector
immediatamente e quindi non vengono deallocate immediatamente le
risorse associate alla connessione, oppure anche dal SO su cui sta
giranto la JVM.
A proposito di quest'ultima ipotesi ho letto che in WinXP con il SP2
sono stati introdotti dei limiti che riguardano le Librerie di sistema
del TCP. In particolare hanno inserito dei limiti che riguardano le
connessioni HalfOpen e sia quelle HalfClosed. E' stato messo un limite
superiore al numero di connessioni HalfOpen, e viene fatto ritardare il
tempo neccessario a deallocare le risorse associate ad una connessione.
(Questi limiti si dice siano stati inseriti per limitare il P2P e in
effetti con Emule me ne sono accorto....).
Cmq sul web puoi trovare delle "patch" diciamo non tanto legali che
risolvono questo problema.. Eccoti il link:
http://forum.hwupgrade.it/showthread.php?s=14ae23d4abbf39ad3f2b4eca2d5b8c1d&threadid=754583
Comunque rispondendo alla tua domanda, ho dato un occhiata alle API di
java.net
 e ho visto che la classe ServerSocket dei metodi interessanti:
boolean: isClosed()  //ti comunica lo stato della connessione
e soprattutto questo:
void setReuseAddress(boolean on)
che ti permette ti abilitare/disabilitare l'opzione SO_REUSEADDR
Abilitando questa opzione puoi fare il bind di una porta sulla quale
c'e' stata precedentemente una connessione che attualmente si trova in
timeout(ovvero in attesa di essere deallocata).
Fammi sapere, Ciao

Fammi sapere, Ciao
Provo in giornata e ti faccio sapere!
Ciao e Grazie!

boolean: isClosed()  //ti comunica lo stato della connessione
Mi sono reso conto che lo ho chiesto per nulla: quando ho capito che
il server ha chiuso la connessione definitivamente come lo comunico al
client, senza connessione?
Adesso che ho capito  un pò come funzionano le cose, rifaccio il
programma con un'unica connessione, come avevi giustamente suggerito
all'inizio.
Grazie mille dell'aiuto, sei stato veramente gentile...
Wakko Kid.

client, senza connessione?
Potresti fare che il server appena finisce di ricevere il file, mandi
un messaggio (
ad.es
 un codiceOperitivo) al client per segnalarli che
sta chiudendo la connessione.
Questo messaggio puo' essere appunto una banale stringa, un intero...
oppure addiritura un oggetto che pero' deve implementare l'interfaccia
java.io.Serializable. Nel caso di un oggetto per trasmetterlo nella
rete non dovrai fare nient'altro che fare una write lato server su un
ObjectOutputStream che rappresenta un astrazione dell'Outputstream
associato al Socket. Quindi lato client una read su un
ObjectInputStream.

sta chiudendo la connessione.
Intendevo che il metodo isClosed() mi dice che la connessione ora è
chiusa. Dunque se la connessione è chiusa non posso inviare nulla al
client, che sia un oggetto o un messaggio no? Il tutto era ancora
riferito alla "versione corrente" del programma che apre una
connessione per ogni file, nella futura versione, dove tutto sarà
eseguito con una sola connessione, ovviamente sincronizzerò Client e
Server medianta messaggi convenuti (come già avviene parzialmente per
quanto riguarda nome e posizione dei files trasferiti)
Ciao
Wakko Kid

 writes:
jp> Ciao, sinceramente non so quanto tempo possa intercorrere tra
jp> l'installazione di 2 ServerSocket sulla stessa porta. Questo tempo
jp> puo' dipendere sia dalla JVM che non fa girare il GarbageCollector
jp> immediatamente e quindi non vengono deallocate immediatamente le
jp> risorse associate alla connessione, oppure anche dal SO su cui sta
jp> giranto la JVM.
Diamine, è il sistema. Perché ci si metta un tot lo si desume andandosi
a vedere come si apre e chiude una connessione TCP/IP...
jp>  A proposito di quest'ultima ipotesi ho letto che
jp> in WinXP con il SP2 sono stati introdotti dei limiti che
jp> riguardano le Librerie di sistema del TCP. In particolare hanno
jp> inserito dei limiti che riguardano le connessioni HalfOpen e sia
jp> quelle HalfClosed.
A naso è un tentativo di prevenire alcuni DoS...
-- 
 /\            ___
/___/\__|_|\_|__|___Gian Uberto Lauri_____________________
  //--\ | | \|  |   Integralista GNUslamico  
\/		    e coltivatore diretto di software