简体   繁体   中英

The server is sending data through the socket, but the client is not receving it (Java)

I am writing a file storage and transfer system using Java. Here's the code on the client side to receive a file:

public static void receiveFile(Socket socket) throws IOException{   
    String fileLocation="/home/limafoxtrottango/Downloads/receivedFile";
    int bytesRead=0;
    int current = 0;
    FileOutputStream fileOutputStream = null;
    BufferedOutputStream bufferedOutputStream = null;

    try {
        // receive file
        byte [] byteArray  = new byte [60022386];
        System.out.println("Waiting to receive a file...");
        //reading file from socket
        InputStream inputStream = socket.getInputStream();
        fileOutputStream = new FileOutputStream(fileLocation);
        bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        bytesRead = inputStream.read(byteArray,0,byteArray.length);                 //copying file from socket to byteArray
        current = bytesRead;
        do {
            bytesRead =inputStream.read(byteArray, current, (byteArray.length-current));
            if(bytesRead >= 0) current += bytesRead;
        } while(bytesRead > -1);
        bufferedOutputStream.write(byteArray, 0 , current);                         //writing byteArray to file
        bufferedOutputStream.flush();                                               //flushing buffers

        System.out.println("File " + fileLocation  + " downloaded ( size: " + current + " bytes read)");
    } catch(SocketException e){
        System.out.println("Some error occured");
    }
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    finally {
        if (fileOutputStream != null) fileOutputStream.close();
        if (bufferedOutputStream != null) bufferedOutputStream.close();
        if (socket != null) socket.close();
    }
}

While receiving a file, I get the following error:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at java.io.BufferedOutputStream.write(BufferedOutputStream.java:128)
    at Test.receiveFile(Test.java:211)
    at Test.main(Test.java:70)

Note: The error is in the following line of the code:

bufferedOutputStream.write(byteArray, 0 , current);  

After debugging, I found-out that the client does not have any data in it's input stream, and hence, the read() method always returns -1 (eof). But the server is sending the file successfully.

Here is the code for the server:

public static void sendFile(Socket socket, String fileLocation)
{
    FileInputStream fileInputStream = null;
    BufferedInputStream bufferedInputStream = null;
    OutputStream outputStream = null;
    File file = new File (fileLocation);
    byte [] byteArray  = new byte [(int)file.length()];
    try {
        socket=new Socket(socket.getInetAddress(),port_no);
        fileInputStream = new FileInputStream(file);
        bufferedInputStream = new BufferedInputStream(fileInputStream);
        bufferedInputStream.read(byteArray,0,byteArray.length); // copied file into byteArray

        //sending file through socket
        outputStream = socket.getOutputStream();
        System.out.println("Sending " + fileLocation + "( size: " + byteArray.length + " bytes)");
        outputStream.write(byteArray,0,byteArray.length);           //copying byteArray to socket
        outputStream.flush();                                       //flushing socket
        System.out.println("Done sending!");    
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

And here is my call to the above method:

sendFile(clientSocket, "/home/limafoxtrottango/Downloads/serverDownloads/"+sender);

The thing is that the server is successfully writing the byte into the stream, but the client doesn't seem to have any data in it's input stream.

https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read(byte[],%20int,%20int)

inputStream.read(byteArray,0,byteArray.length); may return -1 in some cases as given in documentation above. Please cater for such situations.

In addition, I would suggest to use solution given here for both client and server: Efficient way to write InputStream to a File in Java (Version 6)

Client code:

final Path destination = Paths.get(fileLocation);
try (
    final InputStream in = socket.getInputStream();
) {
    Files.copy(in, destination);
}

Server code:

try (
    final InputStream in = new FileInputStream(fileLocation);
) {
    Files.copy(in, socket.getOutputStream());
}

Kind regards, Bala

The server isn't sending anything, contrary to your title. It is closing the connection immediately, so bytesRead is initially -1 and never changes, and you aren't defending against that, so you get the ArrayIndexOutOfBoundsException .

However in the code you posted, the server is sending something but never closing the socket, which is another bug you need to fix. It is also ignoring the count returned by FileInputStream.read() and assuming it filled the buffer, which isn't part of the specification.

So either this is not the real server code or you are connecting to something else, or the server got an IOException that you haven't mentioned.

It's curious that you use two different pieces of code for copying. The standard way to copy a stream in Java is this:

char buffer = new char[8192]; // or whatever size you prefer > 0
int count;
while ((count = in.read(buffer)) > 0)
{
    out.write(buffer, 0, count);
}

Use this at both ends. There is no need for heroically sized buffers, or buffers the size of the file, or assuming that the file size fits into an int .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM