Estimados:
Tengo un problema con un envío de ficheros, el problema es que el socket o hilo, en realidad no se, se bloquea. esta es la clase que usa el cliente y el servidor para el envio y recepción de ficheros. Dejo en claro que esto solo envía ficheros de textos. La verdad es que no tengo problemas al enviar o recibir un fichero de texto por localhost, el problema viene cuando uso internet. Solo logro enviar y recibir textos como por ejemplo el nombre del usuario, dirección, cosas así. Alguien tendría la amabilidad de ayudarme por favor.
Pd: Es un servidor que gestiona multiples clientes. Estas funciones son usadas el metodo run().
El servidor recibe 2 archivos, y responde con un archivo.
package Mensaje;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Mensaje para pedir un fichero.
*/
public class DameFichero
{
public Socket socket;
public DameFichero(Socket socket)
{
this.socket = socket;
}
public String leerArchivoNotas(String nombreFileNotas)
{
File archivo;
String linea;
FileReader fr = null;
BufferedReader br = null;
FileWriter archivoResultado;
PrintWriter pw = null;
try
{
// Apertura del fichero y creacion de BufferedReader para poder
// hacer una lectura comoda (disponer del metodo readLine()).
archivo = new File (nombreFileNotas);
fr = new FileReader (archivo);
br = new BufferedReader(fr);
archivoResultado = new FileWriter("resul_"+nombreFileNotas);
pw = new PrintWriter(archivoResultado);
// Lectura del fichero
int contador = 0;
//leemos las lineas que no nos sirven para calcular las notas
linea=br.readLine();
linea=br.readLine();
linea=br.readLine();//en esta linea los nombres de las columnas
pw.println(linea+"\tPromedio_final");// le agregamos una ultima colum
while((linea=br.readLine())!=null)
{
try
{
//filtramos por tokens
StringTokenizer st = new StringTokenizer(linea,"\t");
float C1, C2, C3, NE;
//quitamos los tokens que no nos sirven
for (int i = 0; i < 3; i++)
st.nextToken();
C1 = Float.parseFloat(st.nextToken());
C2 = Float.parseFloat(st.nextToken());
C3 = Float.parseFloat(st.nextToken());
NE = Float.parseFloat(st.nextToken());
//escribimos la nota al final de cada columna
pw.println(linea+"\t"+Redondear(getNotaFinal(C1,C2,C3,NE)));
}
catch (Exception e)
{
System.out.println("problemas con el numero flotante");
e.printStackTrace();
}
}
}
catch(Exception e){
e.printStackTrace();
}
finally
{
// En el finally cerramos el fichero, para asegurarnos
// que se cierra tanto si todo va bien como si salta
// una excepcion.
try
{
fr.close();
br.close();
pw.close();
}
catch (Exception e2){
e2.printStackTrace();
}
}
return "resul_"+nombreFileNotas;
}
public void EnviarArchivo(String nombreArchivo)
{
PrintWriter pw1 = null;
BufferedReader br1 = null;
try
{
// Creamos el archivo que vamos a enviar
File archivo = new File(nombreArchivo);
if(!archivo.exists())
{
System.out.println("El archivo a "+nombreArchivo+" no existe");
return ;
}
// Obtenemos el tamaño del archivo
int tamañoArchivo = (int)archivo.length();
File filenombreArchivo = new File(nombreArchivo);
// Creamos flujo de entrada para realizar la lectura del archivo en bytes
FileReader fr = new FileReader(filenombreArchivo);
String buffer;
int i = 1;
pw1 = new PrintWriter(this.socket.getOutputStream(), true);
br1 = new BufferedReader(fr);
System.out.println("El tamaño del archivo a enviar: "+tamañoArchivo);
/*
synchronized (pw1)
{
*/
while((buffer=br1.readLine())!=null)
{
pw1.println(buffer);
System.out.println(i+") "+buffer.length());
try {
Thread.sleep(100);//le puse este sleep para depurar
} catch (InterruptedException ex) {
System.out.println("Excepcion del sleep()");
//Logger.getLogger(DameFichero.class.getName()).log(Level.SEVERE, null, ex);
}
i++;
}
// pw1.notify();
//}
fr.close();
}
catch(IOException e)
{
System.err.println(e.toString());
}
finally
{
try
{
br1.close();
//pw1.close();
}
catch (IOException ex) {
Logger.getLogger(DameFichero.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public void RecibirArchivo(String nombreArchivo, int tam)
{
PrintWriter pw2 = null;
BufferedReader br2 = null;
try
{
String buffer;
int i = 1;
File filenombreArchivo = new File(nombreArchivo);
FileWriter fw = new FileWriter(filenombreArchivo);
pw2 = new PrintWriter(fw);
br2 = new BufferedReader(new InputStreamReader(
this.socket.getInputStream()));
//synchronized (br2)
{
/* try {
br2.wait();
} catch (InterruptedException ex) {
Logger.getLogger(DameFichero.class.getName()).log(Level.SEVERE, null, ex);
}*/
//br2.notify();
//socket.setSoTimeout(4* 1000);
while ((buffer = br2.readLine())!=null)
{
pw2.println(buffer);
System.out.println(i+") "+buffer.length());
try {
Thread.sleep(100);//le puse este sleep solo para depurar
} catch (InterruptedException ex) {
System.out.println("Excepcion del sleep()");
//Logger.getLogger(DameFichero.class.getName()).log(Level.SEVERE, null, ex);
}
i++;
}
}
fw.close();
}
catch (IOException e)
{
System.out.println("timout liberado");
//e.printStackTrace();
}
finally
{
pw2.close();
//br2.close();
}
}
}
El problema era que definía varios stream y lo asociaba a un mismo socket, ejemplo: declaraba un BufferOutputStream y un PrintWriter como flujos de salida y lo asociaba a un socket, ocasionando problemas en la conexión (pérdida de datos). El error no estaba en esa clase, sino en donde se instanciaba.