Question

I have probably been staring at this too long and can't see what the problem is.

I have a server which accepts multiple client connections and saves the sockets. The server can then send out control messages to the clients to perform tasks and, among other things, I want to send files out to all the connected clients but the client only seems to receive part of them.

For testing purposes I have a randomly generated text file 69075 bytes but although it seems like whole whole file is sent, the client only receives upto around 57000 bytes (varies). I have added a button on the server app which lets me close the client socket and when I do that the client receives -1 followed by the rest of the missing file.

Server sending file:

      try {
       getClientList().get(0).setLocked(true);                                          
       byte [] mybytearray  = new byte [1024];

       BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));  
       OutputStream os = getClientList().get(0).getmSocket().getOutputStream();

       Boolean eof = false;
       int bytesRead;
       int total = 0;
       do {
           bytesRead = bis.read(mybytearray, 0, mybytearray.length);
           if (bytesRead != -1) {                               
               os.write(mybytearray, 0, bytesRead);
               total += bytesRead;                              
               Log.d(TAG_SF, "Total: "+total+" :Sent: "+ bytesRead);
           } else {
               eof = true;
               Log.d(TAG_SF, "EOF, Total sent: " + total);
           }
       } while (!eof);                        
       os.flush();
       bis.close();                                      
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        getClientList().get(0).setLocked(false);
    }

A message is sent to the clients with the file name and file size before the file is send and it is received ok.

Client receiving file:

        try {
        int total = 0;
        byte[] myByteArray = new byte[1024];
        int bytesRead;
        InputStream is = serverSocket.getInputStream();
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream(path+SD_DIRECTORY+fileName));   

        do {
            bytesRead = is.read(myByteArray, 0, myByteArray.length);
            if (bytesRead != -1){
                bos.write(myByteArray, 0, bytesRead);           
              total = total+bytesRead;
              Log.e(TAG,"Total > "+total+ ": No Bytes : "+bytesRead);
            } else {
              Log.e(TAG,"EOF, total received: "+total);
              break;
            }
        } while (total < fileLength);  //fileLength and filename are sent before file           
        Log.e(TAG,"Total > "+total+ ": No Bytes : "+bytesRead);             
        bos.flush();
        bos.close();
       } catch (Exception e) {             
           e.printStackTrace();
       }

No correct solution

OTHER TIPS

The problem was not with the code for sending and receiving, it works fine.

I was sending a message to the client first with a control code indicating a file was to be send, followed by the file size and file name. The client then waits for the file but the server started sending before the client was ready and was missing the start of the file.

To test, put the server thread to sleep for a couple of seconds after sending the file name and before sending the file and it works fine. I will probably have the client send a 'ready' message to the server as a better solution.

EDIT: Although this worked, it is not the answer, it does seem to be related to using both buffered and unbuffered streams (see EJP comment). Will do a bit of re writing and update accordingly. Not sure of SO protocol, should I delete a wrong answer?

EDIT (again) EJPs comment is absolutely correct, it was related to having a buffered input stream open to receive the file name and then opening an unbuffered stream elsewhere to transfer the file. My knowledge is limited in this area (and generally) so I just re wrote to use the same unbuffered stream for both.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top