0

I'm trying to send file using Sockets, but when I receive the file, I can't store it. Debugger shows, that code stops at

bytesRead = is.read(mybytearray, current, (mybytearray.length - current));

and nothing happens.

bytesRead = is.read(mybytearray, 0, mybytearray.length); - is equal 17

public static void main(String[] args) throws IOException {
            FileOutputStream fileOutputStream = null;
            BufferedOutputStream bufferedOutputStream = null;
            Socket socket = null;
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(SOCKET_PORT);
                while (true) {
                    System.out.println("Waiting...");
                    try {
                        socket = serverSocket.accept();
                        System.out.println("Accepted connection : " + socket);
                        int bytesRead;
                        int current = 0;
                        byte[] mybytearray = new byte[FILE_SIZE];
                        InputStream is = socket.getInputStream();
                        fileOutputStream = new FileOutputStream(FILE_TO_RECEIVED);
                        bufferedOutputStream = new BufferedOutputStream(bufferedOutputStream);
                        bytesRead = is.read(mybytearray, 0, mybytearray.length);
                        current = bytesRead;

                        do {
                            bytesRead =
                                    is.read(mybytearray, current, (mybytearray.length - current));
                            if (bytesRead >= 0) current += bytesRead;
                        } while (bytesRead > -1);

                        bufferedOutputStream.write(mybytearray, 0, current);
                        bufferedOutputStream.flush();
                        System.out.println("File " + FILE_TO_RECEIVED
                                + " recieved (" + current + " bytes read)");


                    } finally {
                        if (fileOutputStream != null) fileOutputStream.close();
                        if (bufferedOutputStream != null) bufferedOutputStream.close();
                        if (socket != null) socket.close();
                    }
                }
            } finally {
                if (serverSocket != null) serverSocket.close();
            }
        }
Little Fox
  • 1,212
  • 13
  • 39

3 Answers3

1

You can try writing directly to the OutputStream instead e.g. changing your while-loop into

while ((bytesRead = in.read(mybytearray)) > 0) {
    fileOutputStream.write(mybytearray, 0, bytesRead);
}

as per the description in the answer by Rookie - https://stackoverflow.com/a/9548429/2826895

Jotunacorn
  • 496
  • 1
  • 4
  • 12
1

since you have a variable named FILE_SIZE, i'll assume you know the size of your file.

Instead of reading from the stream until you stop getting data: while (bytesRead > -1), you might want to try stopping when you don't expect any more data: while (bytesRead > -1 && current<FILE_SIZE)

If you don't always know the size of the file, then you need to also communicate that size through the socket. This could simply be an integer denoting the file size, but possibly also something like the chunked encoding used in HTTP.

Thijs Steel
  • 1,190
  • 7
  • 16
0

The problem is in these two lines, as hinted at by user Thijs Steel:

bytesRead = is.read(mybytearray, current, (mybytearray.length - current));
if (bytesRead >= 0) current += bytesRead;

After soon as you read the last bytes, current becomes equal to mybytearray.length (assuming that FILE_SIZE is indeed the size of the file in bytes). From then on you have an infinite loop that requests zero bytes to be read, which read dutifully does and returns zero.

Make your loop stopping condition to be either upon receiving end-of-file (EOF) or after reading FILE_SIZE bytes, but not both.

To use EOF as a stopping condition, your read loop needs to be modified to use a byte buffer of fixed length in the read. To use the FILE_SIZE as a stopping condition is much simpler. You simply wrap the inputstream in a DataInputStream and use the readFully() method, as in

DataInputStream dis =  new DataInputStream(is);
dis.readFully(mybytearray);
President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
  • why not both? If the loop stopping condition is EOF (what we have now) we get infinite loop. If the loop stopping condition is reading FILE_SIZE bytes, then it would fail to stop in case of a network condition – Thijs Steel Jul 12 '17 at 12:31
  • @ThijsSteel: I need to clarify my answer – President James K. Polk Jul 12 '17 at 12:32
  • I think `FILE_SIZE` is a constant. It wasn't mentioned anywhere in the code, and from the capitalization one can assume it's a constant. – RealSkeptic Jul 12 '17 at 13:17