Neeraj Athalye
Neeraj Athalye

Reputation: 547

Send multiple files over Java sockets

I know why my problem is occurring but I do not know how to solve it. I am sending multiple files from sender to receiver by sending the following things:

  1. Number of files
  2. File Name
  3. File Size
  4. File data(in bytes)

I am making use of readInt(), readUTF() and readLong() to send the first 3 in my list. For the file data I am making use of a buffer by implementing the following code:

float bytesRead = 0;
int count;
byte[] buffer = new byte[8192];
while ((count = in.read(buffer)) > 0) {
      out.write(buffer, 0, count);
      bytesRead += count;
      Float[] progressData = {(bytesRead / 1000), (float) (size / 1000), (float) i, (float) totalFileCount};
      publishProgress(progressData);
}

I am making use of a for loop to send all the details of the files.

The problem here is that after reading the first file's data, the receiver reads the next file's name also as the first file's data. I need to somehow get it to stop reading after it has reached the size of the first file. But I am unable to implement that. Any help is appreciated.

This is the code for both receiving and sending the data:

Sending

try {
        Socket client = new Socket();
        client.bind(null);
        client.connect(new InetSocketAddress(groupOwnerAddress, 8888));

        if(client.isConnected())
        {
            ((FileTransferActivity) context).setStatus("Connected to Device");
            DataOutputStream out = new DataOutputStream(client.getOutputStream());

            out.writeInt(encryptedFiles.size()); // send number of files

            for(int i = 0; i < encryptedFiles.size(); i++)
            {

                long length = encryptedFiles.get(i).length();
                if (length > Integer.MAX_VALUE) {
                    System.out.println("File is too large.");
                } else {
                    out.writeUTF(encryptedFiles.get(i).getName()); //send file name
                    out.writeLong(length); // send file length

                    DataInputStream in = new DataInputStream(new FileInputStream(encryptedFiles.get(i)));

                    float bytesRead = 0;
                    int count;
                    byte[] buffer = new byte[8192];
                    while ((count = in.read(buffer)) > 0) {
                        out.write(buffer, 0, count);
                        bytesRead += count;
                        Float[] progressData = {(bytesRead / 1000), (float) (length / 1000), (float) i, (float) encryptedFiles.size()};
                        publishProgress(progressData);

                    }
                }
            }
        }

        client.close();

    } catch (IOException e) {
        e.printStackTrace();
    }

Receiving

File directory = new File(directoryPath);
        if(!directory.exists())
            directory.mkdirs();

        String data = null;

            try {
                server = new ServerSocket(8888);
                client = server.accept();
                DataInputStream in = new DataInputStream(client.getInputStream());

                int totalFileCount = in.readInt();

                for(int i = 0; i < totalFileCount; i++)
                {
                    String fileName = in.readUTF();
                    long size = in.readLong();

                    FileOutputStream out = new FileOutputStream(new File(directoryPath + File.separator + fileName));

                    float bytesRead = 0;
                    int count;
                    byte[] buffer = new byte[8192]; // or 4096, or more
                    while ((count = in.read(buffer)) > 0) {
                        out.write(buffer, 0, count);
                        bytesRead += count;
                        Float[] progressData = {(bytesRead / 1000), (float) (size / 1000), (float) i, (float) totalFileCount};
                        publishProgress(progressData);
                    }

                }

            }

                catch (IOException e) {
                    e.printStackTrace();
                }

I have omitted the other functions of the asynctask here as I don't think they are relevant. In any case, if you want me to include that too, just mention it in a comment and I will update my answer with them

Upvotes: 0

Views: 110

Answers (1)

glenebob
glenebob

Reputation: 1983

I didn't run this through javac, but it should work:

int count;
byte[] buffer = new byte[8192];

while (size > 0 && (count = in.read(buffer, 0, Math.min((int) size, buffer.length))) > 0) {
    size -= count;
    out.write(buffer, 0, count);
    // Progress reporting omitted.
}

Upvotes: 2

Related Questions