servidor - socket java ejemplo
Java transferencia de archivos mĂșltiples a travĂ©s de socket (2)
Está leyendo el socket hasta que read()
devuelva -1. Esta es la condición de fin de ciclo (EOS). EOS sucede cuando el par cierra la conexión. No cuando termina de escribir un archivo.
Debe enviar el tamaño del archivo antes de cada archivo. Ya estás haciendo algo similar con el conteo de archivos. Luego, asegúrese de leer exactamente tantos bytes para ese archivo:
String filename = dis.readUTF();
long fileSize = dis.readLong();
FileOutputStream fos = new FileOutputStream(filename);
while (fileSize > 0 && (n = dis.read(buf, 0, (int)Math.min(buf.length, fileSize))) != -1)
{
fos.write(buf,0,n);
fileSize -= n;
}
fos.close();
Puede encerrar todo esto en un bucle que finaliza cuando readUTF()
arroja EOFException
. Por otro lado, por supuesto, debe llamar a writeUTF(filename)
y writeLong(filesize)
al remitente, antes de enviar los datos.
Ok, tratando de transferir un directorio específico de archivos a través de un socket, elimine los objetos de directorio de la lista de arrays, de modo que solo queden archivos, y transfiéralos 1 por 1 en el mismo socket. La lista de arrays aquí está llena de SOLO archivos, sin directorios. Aquí está el código de recepción y envío para el cliente y el servidor, respectivamente. El código funciona bien sin errores, a excepción de TODOS los datos se escriben en el primer archivo. Los archivos siguientes se crean en la carpeta del servidor, pero tienen 0 bytes. Cualquier contribución será muy apreciada.
ESTE ES EL CÓDIGO DE SERVIDOR PARA RECIBIR LOS ARCHIVOS
public void receive(){
try {
DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
//read the number of files from the client
int number = dis.readInt();
ArrayList<File>files = new ArrayList<File>(number);
System.out.println("Number of Files to be received: " +number);
//read file names, add files to arraylist
for(int i = 0; i< number;i++){
File file = new File(dis.readUTF());
files.add(file);
}
int n = 0;
byte[]buf = new byte[4092];
//outer loop, executes one for each file
for(int i = 0; i < files.size();i++){
System.out.println("Receiving file: " + files.get(i).getName());
//create a new fileoutputstream for each new file
FileOutputStream fos = new FileOutputStream("C://users//tom5//desktop//salestools//" +files.get(i).getName());
//read file
while((n = dis.read(buf)) != -1){
fos.write(buf,0,n);
fos.flush();
}
fos.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ESTE ES EL CÓDIGO DEL CLIENTE PARA ENVIAR LOS ARCHIVOS
public void send(ArrayList<File>files){
try {
DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
System.out.println(files.size());
//write the number of files to the server
dos.writeInt(files.size());
dos.flush();
//write file names
for(int i = 0 ; i < files.size();i++){
dos.writeUTF(files.get(i).getName());
dos.flush();
}
//buffer for file writing, to declare inside or outside loop?
int n = 0;
byte[]buf = new byte[4092];
//outer loop, executes one for each file
for(int i =0; i < files.size(); i++){
System.out.println(files.get(i).getName());
//create new fileinputstream for each file
FileInputStream fis = new FileInputStream(files.get(i));
//write file to dos
while((n =fis.read(buf)) != -1){
dos.write(buf,0,n);
dos.flush();
}
//should i close the dataoutputstream here and make a new one each time?
}
//or is this good?
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Lo hice así, está funcionando perfectamente, puedes echar un vistazo:
send
byte[] done = new byte[3];
String str = "done"; //randomly anything
done = str.getBytes();
for(int i =0; i < files.size(); i++){
System.out.println(files.get(i).getName());
FileInputStream fis = new FileInputStream(files.get(i));
while((n =fis.read(buf)) != -1){
dos.write(buf,0,n);
System.out.println(n);
dos.flush();
}
//should i close the dataoutputstream here and make a new one each time?
dos.write(done,0,3);
dos.flush();
}
//or is this good?
dos.close();
recieve
for(int i = 0; i < files.size();i++){
System.out.println("Receiving file: " + files.get(i).getName());
//create a new fileoutputstream for each new file
fos = new FileOutputStream("C://users//tom5//desktop//salestools//" +files.get(i).getName());
//read file
while((n = dis.read(buf)) != -1 && n!=3 ){
fos.write(buf,0,n);
fos.flush();
}
fos.close();
}