PDA

View Full Version : [Java] Problema invio file server-client


misantrophia
18-09-2006, 10:27
Spiego la mia situazione:
nel programma in questione il client si connette al server e tra i vari servizi a lui disponibili c'e' quella di inviare file al server e ricevere file dal server.
La comunicazione e' gestita attraverso i socket e per il "normale" dialogo col server utilizzo due oggeti: uno BufferedReader e l'altro PrintWriter.

Quando arriva il momento di trasferire un file (per esempio da server a client) posso utilizzare questi 2 oggetti che ho (il PrintWriter per il server e il BufferedReader per il client)? Perche' guardando sulla doc il PrintWriter non ha un metodo per inviare dei byte.

Ho provato a fare cio' appoggiandomi ad altri 2 oggetti facendo nel seguente modo:

// Server che invia il file
DataOutputStream out = new DataOutputStream(client.getOutputStream());
FileInputStream in = new FileInputStream(clientFile.getAbsolutePath());
byte buffer[] = new byte[1024];
System.out.println( "Invio file in corso..." );
int i;
while((i = in.read(buffer,0,buffer.length)) != -1){
out.write(buffer,0,i);
out.flush();
}
in.close();
System.out.println( "Invio completato." );

//Client che riceve il file
System.out.println("Ricezione file in corso..");
DataInputStream in = new DataInputStream(socket.getInputStream());
FileOutputStream out = new FileOutputStream(lDir + fileName);
byte buffer[] = new byte[1024];
int i;
while ((i = in.read(buffer,0,buffer.length)) != -1){
System.out.println("ci sono");
out.write(buffer,0,i);
}
out.flush();
out.close();
System.out.println( "Ricezione completata!" );


In questo modo pero' mi si verificano 2 casi:
- il server invia il file, il client non entra nel ciclo while e mi ritrovo in locale il file vuoto.
- il server invia il file, il client entra nel ciclo while ma non esce e rimane in attesa infinita, in locale mi ritrovo il file pieno.

Per cercare di evitare il secondo caso, ho provato a chiudere il DataOutputStream sul server, la trasmissione si completa con successo, ma questo mi fa chiudere il socket e quindi la comunicazione col server.

Come risolvere? Il ciclo while impostato in questo modo e' corretto?
Grazie mille a chi risponde!!!

TempestaT400
18-09-2006, 10:32
Guarda, ho postato in un altro 3d il metodo di invio di un file da un server ad un client.!.
Non so se ti può essere utile... controlla tu stesso!!!

http://www.hwupgrade.it/forum/showthread.php?t=1281150

misantrophia
18-09-2006, 10:53
Ma utilizzando DatagramPacket e DatagramSocket, non si effettua una trasmissione UDP?

texerasmo
18-09-2006, 11:19
Puoi provare con webdav.
Oppure puoi fare un classe che far upload di un file (in rete ne trovi mille) e poi la fai diventare una servlet.
così la richiami e il gioco è fatto

misantrophia
18-09-2006, 14:49
Puoi provare con webdav.
Oppure puoi fare un classe che far upload di un file (in rete ne trovi mille) e poi la fai diventare una servlet.
così la richiami e il gioco è fatto

Sarebbe bello, pero' devo riuscire a farlo io in java.

TempestaT400
18-09-2006, 18:37
Ma utilizzando DatagramPacket e DatagramSocket, non si effettua una trasmissione UDP?

DatagramPacket e DatagramSocket servono per le connessioni UDP ma se hai un pò di esperienza sulla programmazione impieghi pochissimo per trasformare il listato per connessioni TCP

TempestaT400
19-09-2006, 00:18
Eccoti il codice con la connessione TCP...

SERVER



import java.io.*;
import java.net.*;
import java.util.*;

public class Server {
public static final int PORT = 4444; // porta al difuori del range 1-1024 !
public static final String FILE = "file.txt";
ServerSocket socket;
static BufferedReader in = null;
static boolean moreLines = true;

public Server(){
try {
// creazione della socket
socket = new ServerSocket(PORT);
System.out.println("Socket: " + socket);
} catch (Exception e) {System.err.println("Unable to create the socket");}
try {
// associazione di uno stream
// di input al file da cui estrarre le linee
in = new BufferedReader(new FileReader(FILE));
System.out.println("File "+FILE+" opened");
} catch (FileNotFoundException e)
{
System.err.println("Could not open");
}
}

public static void main(String[] args) throws IOException {
System.out.println("LineServer: started");
Server server=new Server();
Socket client = server.socket.accept();
PrintWriter out = new PrintWriter(new BufferedOutputStream(client.getOutputStream()),true);

while (moreLines) {
try {


// preparazione della linea da inviare
String dString = null;
if (in == null)
dString = new Date().toString();
else
dString = getNextLine();

if (dString!=null) {
//invio linea file
out.println(dString);
System.out.println("Sending packet to "+client.getInetAddress()+" port:"+client.getPort());
}
else{
out.println("null");
}
} catch (Exception e) {
e.printStackTrace();
moreLines = false;
}
}

System.out.println("No more lines. Goodbye.");
System.out.println("LineServer: closing...");
in.close();
out.close();
server.socket.close();
}

static String getNextLine() {
String returnValue = null;
try {
if ((returnValue = in.readLine()) == null) {
in.close();
moreLines = false;
returnValue = null;
//returnValue = "No more lines. Goodbye.";
}
} catch (IOException e) {
returnValue = "IOException occurred.";
}
return returnValue;
}
}



CLIENT



import java.io.*;
import java.net.*;


public class Client {

public static void main(String[] args) throws IOException {
// creazione della socket
InetAddress serverAddress = InetAddress.getLocalHost();
int port = 4444;

Socket socket = new Socket(serverAddress, port);
System.out.println("LineClient: started");
System.out.println("Socket: "+ socket);
PrintWriter out = new PrintWriter(new FileWriter("ric.txt"), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
//ricezione linea file.
String received = in.readLine();
if(received.trim().equals("null"))
break;
else
out.println(received.trim());
}
System.out.println("LineClient: closing...");
out.close();
in.close();
socket.close();
}
}


é normale che per funzionare bisogna che sia presente il file "file.txt" nella cartella delle classi!
Altrimenti verra catturata l'eccezione FileNotFoundException!

Ciao ciao

texerasmo
19-09-2006, 10:19
Questo è un esempio di connessione webdav.
Per fare un test di basta prendere tomcat abilitare webdav

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;

import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpURL;
import org.apache.webdav.lib.WebdavResource;

public class SlideTest {

public static void main (String args[])
{
try
{
HttpURL hrl =
new HttpURL("http://192.168.0.110:8080/webdav/mino");
//user e pass se la gestisci la coas con tomcat-user.xml
hrl.setUserinfo("viru","tomcat");
WebdavResource wdr =
new WebdavResource(hrl);
File fn = new File("SlideTest.class");
//prendo unfile
// wdr.getMethod(fn);
String path = wdr.getPath() + "/" + fn;
//metto un file
boolean rslt = wdr.putMethod(path,fn);
System.out.println("path " + path);
System.out.println("the value of boolean is " + rslt);
//creo una folder in remoto
//boolean status = wdr.mkcolMethod(wdr.getPath() + "/arma");
//System.out.println("MKCOL Status = " + status);
wdr.close();



}
catch(MalformedURLException mue)
{
}
catch(HttpException he)
{
}
catch(IOException ioe)
{
}
}
}



OK funziona TempestaT400 manca una parentesi finale in Server.java,oppure ho sbagliato a fare cp cv

TempestaT400
19-09-2006, 19:44
Si, in effetti ho ricontrollato e mancava una parentesi.!.
Grazie... Cmq,... E' logico che funziona... avevi dubbi'???

PS: ho modificato il codice aggiungendo la parentesi!!!

texerasmo
20-09-2006, 09:39
ASSOLUTAMNETE NO!!!
ERA PER DARE CONFORTO A MISANTROPHIA

TempestaT400
20-09-2006, 11:11
:D