Elias Atahi
Elias Atahi

Reputation: 179

Socket file transfer: Receiver stuck in reading from buffer/writing to storage

static void sendFile(Socket socket, File file) throws IOException {

    File testFile = new File( Environment.getExternalStorageDirectory().toString()+"/DCIM/Camera/Test.jpg");
    byte [] buffer = new byte[(int)testFile.length()];
    FileInputStream fis = new FileInputStream(testFile);
    BufferedInputStream bis = new BufferedInputStream(fis);
    Log.d(DebugTag, "Trying to read testFile from storage into buffer");
    bis.read(buffer,0,buffer.length); 
    Log.d(DebugTag, "Read testFile into buffer");
    OutputStream os = socket.getOutputStream();
    Log.d(DebugTag, "Trying to write testFile from buffer into output stream");
    os.write(buffer, 0, buffer.length);
    Log.d(DebugTag, "Wrote testFile from buffer into output stream");
    os.flush();
    Log.d(DebugTag, "Outputstream flushed");
}

static void receiveFile(Socket socket) throws IOException {

    InputStream is = socket.getInputStream();
    String receivedFileDirectory = Environment.getExternalStorageDirectory().toString()+"/Pictures/receivedFile.jpg";
    File receivedFile = new File(receivedFileDirectory);
    //check if directory exists, otherwise create it
    if (receivedFile.exists()) {
        Log.d(DebugTag, "Filename at destination already exists");
    } else if (!receivedFile.exists()) {
        Log.d(DebugTag, "Filename at destination does not exist, trying to create it!");
        receivedFile.createNewFile();
        Log.d(DebugTag, "Created file!");
    }

    Log.d(DebugTag, "Preparing file reception. Destination:"+receivedFileDirectory);
    OutputStream os = new FileOutputStream(receivedFileDirectory);
    Log.d(DebugTag, "established outputstream to file directory");
    byte[] buffer = new byte[2048];
    int length;
    Log.d(DebugTag, "Trying to read inputstream into buffer and write file to destination");
    while ((length = is.read(buffer)) >0 ) {
        os.write(buffer,0,length);
    }
    Log.d(DebugTag, "File received.");
    os.flush();
    os.close();
    is.close();
    Log.d(DebugTag, "Closed in and out streams");

}

The sender file seems to work perfectly, I get every log message till "outputstream flushed". On the receiver side, everything seems to go well until the code reaches the while loop: The last log msg I get is always "Trying to read inputstream into buffer and write file to destination", but not "File received" and the following messages. Weird thing is: I receive the test file and can open it (though it takes some seconds - don't know if this is typical for android). Any clues why the code gets stuck in the while loop?

Second question: This is my first Android/Java app. Is this code alright for sending and receiving files over sockets? Even if files get bigger (up to >100MB)?

Thanks in advance!

Upvotes: 3

Views: 1784

Answers (1)

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84151

That is.read(buffer) will only return zero if the other side of the connection is gracefully closed (or throw an exception on errors), so what you are missing is the socket.close() on the sending side.

os.flush() is not enough here since TCP does not know when you are done sending data.

Upvotes: 2

Related Questions