Help with Socket and files in Java

0

You see, I'm doing this exercise ...

Create a server client program where a client asks the server for a file and it is sent to the client and then printed on the screen.

The problem I have is that I can not pass the contents of the file, if I create the file on the client side, but the content of the server file is not passed: (

I leave the server code ...

package socket6;
import static java.awt.PageAttributes.MediaType.C;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Socket6 {
    public static void main(String[] args) {
    try {
        ServerSocket servidor=new ServerSocket(4500);
        Socket cliente=servidor.accept();

        FileInputStream file=new FileInputStream("C:\archivoservidor.txt");
        byte b[]=new byte[20002];
        file.read(b,0,b.length);
        OutputStream out=cliente.getOutputStream();
    } catch (IOException ex) {
        Logger.getLogger(Socket6.class.getName()).log(Level.SEVERE, null, ex);
    }

}

}

I leave the Client's code ...

import java.awt.Desktop;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Cliente {
public static void main(String[] args){
    try {
        byte []b=new byte[20002];
        Socket cliente=new Socket("localhost",4500);
        InputStream in=cliente.getInputStream();

        FileOutputStream file=new FileOutputStream("C:\Users\Palomita\Documents\Programacion web\Sockets\archivocliente.txt");
        in.read(b,0,b.length);
        file.write(b,0,b.length);

        File archivo = null;
        FileReader fr = null;
        BufferedReader br = null;
        archivo = new File ("C:\Users\Palomita\Documents\Programacion web\Sockets\archivocliente.txt");
        fr = new FileReader (archivo);
        br = new BufferedReader(fr);
        String linea;
        while((linea=br.readLine())!=null)
            System.out.println(linea);
    } catch (IOException ex) {
        Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
    }

}
}

I hope you can help me, and an apology, I'm new to this from Java hehe: D

    
asked by Paloma Martínez 04.11.2018 в 01:44
source

1 answer

1

There are many problems with your code. let's start on the server side:

...
ServerSocket servidor=new ServerSocket(4500);
Socket cliente=servidor.accept();
FileInputStream file=new FileInputStream("C:\archivoservidor.txt");
byte b[]=new byte[20002]; 

Here we see a problem byte b[]=new byte[20002]; this " buffer " of bytes is Exessive or on the contrary is insufficient. it is not advisable to make a "memory buffer so large without knowing how much you really need, in this case it is recommended and used Files.readAllBytes (java.nio.file.Path) (in English)

Buffer Size recommendation ( in English)

file.read(b,0,b.length);
    OutputStream out=cliente.getOutputStream();
} catch (IOException ex) {
    Logger.getLogger(Socket6.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

and that's it! Where do you send the data to out ? so here the problem is: it is not transmitting NOTHING we must send the bytes that are in b to out by out.write() Another problem GRAVE is that the Streams are not closing! you do not close the reading stream file or the socket (either the server or the client!)

therefore an improved and correct code would be:

import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Socket6 {

public static void main(String[] args) {
//try con recursos (try con autoclose) ver link
    try (ServerSocket servidor = new ServerSocket(4500)) {
        try (Socket SocketCliente = servidor.accept()) {
            byte filebytes[] = null;
            try {
                //se lee TODOS los bytes del archivo a un Byte Array. 
                filebytes = Files.readAllBytes(Paths.get("archivoservidor.txt"));
            } catch (IOException fileex) {
                Logger.getLogger(Socket6.class.getName()).log(Level.SEVERE, "Error en la Lectura del archivo Datos", fileex);
            }
            //si filebytes es nulo significa que la lectura fallo o el archivo esta vacio! 
            if (filebytes != null) {
                //el paso anterior puede tardar mucho necesitamos asegurar que el socket (cliente) aun este disponible(connectado)
                if (!SocketCliente.isClosed() && SocketCliente.isConnected()) {
                    try {
                        OutputStream outstream = SocketCliente.getOutputStream();
                        //tomar los bytes y escribirlos al stream (NOTA esto puede que no Envie los datos para asegurar que se envien debemos usar Flush!
                        outstream.write(filebytes);
                        //flush (enviar los datos al cliente)
                        outstream.flush();
                    } catch (IOException outex) {
                        Logger.getLogger(Socket6.class.getName()).log(Level.SEVERE, "Error en la Transmisión de Datos", outex);
                    }
                } else {
                    Logger.getLogger(Socket6.class.getName()).log(Level.SEVERE, "El Socket esta Cerrado o desconectado");
                }
            }
            System.out.println("done");
        //nota si usamos try with resource no necesitamos hacer close() 
        //PERO! si usamos un "try normal" debemos hacer SocketCliente.close() en el Finally Statement... de **este** try
        //SocketCliente.close();
        }//SocketCliente close implisito
    } catch (IOException ex) {
        Logger.getLogger(Socket6.class.getName()).log(Level.SEVERE, "Exception con el Socket?", ex);
    }// servidor close implisito
    }

}

try with resources (try with autoclose)

The Client has errors in Similar, you do not close the Streams! and you do not do Flush to send the data to the Archive! in each loop.

In addition to this, the lines: in.read(b,0,b.length); and file.write(b,0,b.length); only happen 1 ves (it is not inside a loop). In other words, if 20002 bytes is not all the data in the file, you only save those 20002 bytes and the rest of the file? it is outside or viseversa. if the file is 496 bytes (assuming it is only text in ansii are 62 letters) the file will have invalid data (the rest of the bytes in 0 %code% ) so the result may be inconsistent with the expected. to avoid that you must use loops. see: guide on loops

and therefore for the client to perform the function correctly

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Cliente {

    public static void main(String[] args) {
        byte readbytes[] = new byte[1000];//1000 aunque podriamos usar 4096
        //try with resources socket & inputsstream 
        try (Socket cliente = new Socket("localhost", 4500); InputStream in = cliente.getInputStream()) {
            //try with resourse for the file Write operation
            try (OutputStream FileToFill = Files.newOutputStream(Paths.get("archivocliente.txt"))) {
                //loop para lectura del archivo usamos un for para poder
                //declarar una variable & hacer la verificacion podriamos 
                //usar un While pero necesitariamos 1 variable extra.
                for (int read=-1;(read = in.read(readbytes)) >= 0;) {
                    //se llena los datos a guardar con los Bytes del socket
                    FileToFill.write(readbytes, 0, read);
                    //se imprimimen los bytes leidos 
                    //se asume que usa el mismo <CHARSET> de la PC & que los bytes representan texto
                    System.out.print(new String(readbytes, 0, read));
                    //se graban los bytes al archivo!
                    FileToFill.flush();
                }
            }//implisit file close. 
        } catch (IOException ex) {
            Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
        }//implisit Socket close & input close

    }
}
    
answered by 05.12.2018 в 06:57