Estoy escribiendo una aplicación que necesita enviar un archivo a través de la red. Solo me han enseñado a usar las clases estándar java.net y java.io hasta ahora (en mi primer año de universidad), así que no tengo experiencia con java.nio y netty y todas esas cosas lindas. Tengo un servidor/cliente de trabajo creado usando clases Socket y ServerSocket junto con BufferedInput/OutputStreams y BufferedFile arroyos, de la siguiente manera:¿Cómo puedo almacenar correctamente mi flujo de entrada/salida/archivo Java?
El servidor:
public class FiletestServer {
static ServerSocket server;
static BufferedInputStream in;
static BufferedOutputStream out;
public static void main(String[] args) throws Exception {
server = new ServerSocket(12354);
System.out.println("Waiting for client...");
Socket s = server.accept();
in = new BufferedInputStream(s.getInputStream(), 8192);
out = new BufferedOutputStream(s.getOutputStream(), 8192);
File f = new File("test.avi");
BufferedInputStream fin = new BufferedInputStream(new FileInputStream(f), 8192);
System.out.println("Sending to client...");
byte[] b = new byte[8192];
while (fin.read(b) != -1) {
out.write(b);
}
fin.close();
out.close();
in.close();
s.close();
server.close();
System.out.println("done!");
}
}
y el cliente:
public class FiletestClient {
public static void main(String[] args) throws Exception {
System.out.println("Connecting to server...");
Socket s;
if (args.length < 1) {
s = new Socket("", 12354);
} else {
s = new Socket(args[0], 12354);
}
System.out.println("Connected.");
BufferedInputStream in = new BufferedInputStream(s.getInputStream(), 8192);
BufferedOutputStream out = new BufferedOutputStream(s.getOutputStream(), 8192);
File f = new File("test.avi");
System.out.println("Receiving...");
FileOutputStream fout = new FileOutputStream(f);
byte[] b = new byte[8192];
while (in.read(b) != -1) {
fout.write(b);
}
fout.close();
in.close();
out.close();
s.close();
System.out.println("Done!");
}
}
Al principio no estaba usando el búfer y escribía cada int desde in.read(). Eso me dio una transferencia de 200kb/s según mi gadget de monitor de red en Windows 7. Luego lo cambié como arriba pero usé buffers de 4096 byte y obtuve la misma velocidad, pero el archivo recibido usualmente era un par de kilobytes más grande que el archivo fuente, y ese es mi problema. Cambié el tamaño del búfer a 8192 y ahora obtengo una transferencia de 3.7-4.5mb/seg a través de la conexión inalámbrica a mi computadora portátil, que es lo suficientemente rápido por ahora, pero todavía tengo el problema de que el archivo se haga un poco más grande (lo que causaría fallar una prueba de hash md5/sha) cuando se recibe.
Así que mi pregunta es ¿cuál es la forma correcta de almacenamiento en búfer para obtener velocidades decentes y terminar exactamente con el mismo archivo en el otro lado? Hacer que vaya un poco más rápido también sería bueno, pero estoy contento con la velocidad por ahora. Supongo que un buffer más grande es mejor hasta cierto punto, solo necesito encontrar cuál es ese punto.
Ah, sígueme. – martijno
@martijno Una señal que necesito reducir la velocidad. ;) –
Entiendo que ignorar la parte de tamaño de datos que causa el problema, pero no entiendo eso para el ciclo. De alguna manera, parece que lee adelante de una manera y solo escribe datos desde el búfer hasta el punto donde finaliza el contenido real, ¿es correcto? EDITAR: tiene demasiados corchetes, "((len = ..." debería ser "(len = ..." – Logan