|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Feb 2008
Città: PoggibonZi
Messaggi: 140
|
[JAVA] input e output sulla stessa Socket
Ciao a tutti, devo farvi una domanda riguardo alle Socket, perchè nonostante ci abbia provato e riprovato veramente non riesco a capire....
So che si può comunicare in entrambe le direzioni sulla stessa socket, ma nel mio programma non riesco in nessun modo a farlo....bisogna che le letture/scritture avvengano all'interno dello stesso ciclo ( ) ? Vi spiego in 2 parole...ho creato un programma molto rozzo di file sharing p2p per un esame all'università, e funziona. Il problema è che per aggiornare le liste dei file (client invia la lista dei files locali da condividere, e il server gli rimanda indietro la lista completa dei files disponibili) mi tocca usare 2 socket diverse, una per l'invio e una per la ricezione. La cosa è decisamente brutta, e vorrei che tutto avvenisse sulla stessa socket, dato che da quanto ho capito la cosa si può fare.... In pratica il client manda la lista sulla socket, il server legge dalla socket la lista, la appende alla lista che già possiede, e rimanda quest'ultima (tramite la stessa socket) al client, che la legge e me la visualizza in una JList. Il problema è la parte in neretto, tutto il resto funziona tranquillamente.... Questo è il metodo lato client: Codice:
public void inviaLista()
{
Socket s = null;
try {
s = new Socket();
s.connect(new InetSocketAddress(ip, port));
s.setSoTimeout(timeout);
if (!listaLocali.isEmpty()) listaLocali.clear(); // elimino la vecchia lista e la creo nuova
salvaLista(new File(".")); // verranno condivisi solamente i file nella cartella corrente
BufferedOutputStream bout = new BufferedOutputStream(s.getOutputStream());
ObjectOutputStream out = new ObjectOutputStream(bout);
for (int i=0;i<listaLocali.size();i++)
{
out.writeObject(listaLocali.get(i));
}
// prende indietro la lista
ObjectInputStream inLista = new ObjectInputStream(new BufferedInputStream(s.getInputStream()));
FileProva infl = (FileProva)inLista.readObject();
try
{
while (infl != null)
{
synchronized(listaFiles)
{
listaFiles.add(infl);
}
infl = (FileProva)inLista.readObject();
}
}catch (EOFException eof) {}
synchronized(listaFiles)
{
for (int i=0;i<listaFiles.size();i++)
{
listmodel.addElement(listaFiles.get(i));
}
}
lista.setModel(listmodel);
lista.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
lista.setLayoutOrientation(JList.VERTICAL);
lista.setVisibleRowCount(-1);
inLista.close();
out.flush();
bout.flush();
out.close();
s.close();
} catch (IOException ee) {System.out.println("Errore del client!" ); ee.printStackTrace();}
catch (ClassNotFoundException cnfe) {cnfe.printStackTrace();}
}
Codice:
public void run()
{
try
{
BufferedInputStream bin = new BufferedInputStream(s.getInputStream());
ObjectInputStream in = new ObjectInputStream(bin);
InetAddress client = s.getInetAddress();
synchronized(ServerProva.filesArray)
{
for (int pd=0;pd<ServerProva.filesArray.size();pd++)
{
if (ServerProva.filesArray.get(pd).getOwner().equals(client))
{
ServerProva.filesArray.remove(pd);
pd--;
}
}
}
FileProva inFile = (FileProva)in.readObject();
try
{
while (inFile != null)
{
synchronized(ServerProva.filesArray)
{
ServerProva.filesArray.add(inFile);
inFile = (FileProva)in.readObject();
}
}
}catch (EOFException eof) {}
// Invia al client la lista completa dei files disponibili
// sulla rete
BufferedOutputStream bout = new BufferedOutputStream(s.getOutputStream());
ObjectOutputStream outLista = new ObjectOutputStream(bout);
synchronized(ServerProva.filesArray)
{
for (int i=0;i<ServerProva.filesArray.size();i++)
{
FileProva f = ServerProva.filesArray.get(i);
outLista.writeObject(f);
}
}
in.close();
bout.flush();
outLista.flush();
outLista.close();
s.close();
} catch (InterruptedIOException e) {System.out.println("Timeout in ServerThread");e.printStackTrace();}
catch (IOException ee) {System.out.println("Errore di IO in ServerThread");ee.printStackTrace();}
catch (ClassNotFoundException cnfe) {cnfe.printStackTrace();}
}
Codice:
Errore del client! java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:129) at java.io.BufferedInputStream.fill(BufferedInputStream.java:218) at java.io.BufferedInputStream.read1(BufferedInputStream.java:258) at java.io.BufferedInputStream.read(BufferedInputStream.java:317) at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2266) at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2279) at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2750) at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:780) at java.io.ObjectInputStream.<init>(ObjectInputStream.java:280) at ClientProva.inviaLista(ClientProva.java:128) at ClientProva.aggiorna(ClientProva.java:167) at ClientProva.main(ClientProva.java:202) Codice:
java.net.SocketException: Socket is closed at java.net.Socket.getInputStream(Socket.java:788) at ClientProva.inviaLista(ClientProva.java:131) at ClientProva.aggiorna(ClientProva.java:168) at ClientProva.main(ClientProva.java:203) Errore di IO in ServerThread java.net.SocketException: Socket closed at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:99) at java.net.SocketOutputStream.write(SocketOutputStream.java:136) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123) at ServerThread.run(ServerThread.java:75) É una settimana che il programma sarebbe finito, tranne per questa cagata qui....sarò infinitamente grato a chi mi risolve l'arcano!
__________________
Ho felicemente trattato con: Isomarcus, NLDomy, cipacci. Intel e2180 @ 3.1Ghz + Arctic Cooling Freezer 7 ~ MSI P35 Neo2-FR ~ Geil Black Dragon @ 970Mhz 4-4-4-12 ~ ASUS 8800GT 512Mb ~ OCZ StealthXtream 500W Ultima modifica di m0linas : 17-11-2010 alle 16:22. Motivo: errore di copiatura codice |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Credo che il problema sia in 'inviaLista', qui:
Codice:
...
// prende indietro la lista
ObjectInputStream inLista = new ObjectInputStream(new BufferedInputStream(s.getInputStream()));
FileProva infl = (FileProva)inLista.readObject();
...
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
#3 | |
|
Member
Iscritto dal: Feb 2008
Città: PoggibonZi
Messaggi: 140
|
Quote:
Allora, non ci pensavo che incollando il codice qua non mi riportava i numeri di riga del compilatore....la riga in cui da il timeout, è quella in cui istanzio l'inputstream, non quella dove faccio readObject(). Codice:
...
// prende indietro la lista
ObjectInputStream inLista = new ObjectInputStream(new BufferedInputStream(s.getInputStream()));
FileProva infl = (FileProva)inLista.readObject();
...
__________________
Ho felicemente trattato con: Isomarcus, NLDomy, cipacci. Intel e2180 @ 3.1Ghz + Arctic Cooling Freezer 7 ~ MSI P35 Neo2-FR ~ Geil Black Dragon @ 970Mhz 4-4-4-12 ~ ASUS 8800GT 512Mb ~ OCZ StealthXtream 500W |
|
|
|
|
|
|
#4 | |||
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
L'eccezione è chiarissima: Codice:
java.net.SocketTimeoutException: Read timed out Quote:
Il fatto qui è che quando il client tenta di leggere lo stream di input dal server, i dati non ci sono ne arrivano entro il timeout che gli hai impostato. E i motivi possono essere due (devi verificare quale è il tuo caso): 1) Il server deve ancora inviarli e comunque non arrivano entro il timeout di lettura impostato. 2) Il server li ha già inviati sullo stream, ma poi ha chiuso la connessione e a seguito di questa azione i dati inviati nello stream sono stati scartati: quando il client va a leggere non trova nulla, attende, scade il timeout di lettura e parte l'eccezione. Il punto (2) può verificarsi, lo dice il javadoc di Socket.getInputStream(): Quote:
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 18-11-2010 alle 10:00. |
|||
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 13:53.










) ?










