简体   繁体   中英

Issue with file transfer using Java sockets and DataStreams

I've been working on a chat client for myself and some friends, and decided to attempt to add functionality to allow file transfers between clients. I am able to send a file, but it arrives in a different state than the file sent. As an example, here is a link comparing the before and after of an image sent:

http://i.imgur.com/qbMo0gy.png

Don't ask why I used that picture, it's just the first one I found in my pictures folder... And here are the send and receive methods:

public static Runnable sendFile(String target, File file, Client client) {
            Runnable run = () -> {
                    FileOutputStream fileOut = null;
                    try {
                            int total = 0;
                            int count;
                            byte[] fileBuffer = new byte[8192];
                            BufferedInputStream fileStream = new BufferedInputStream(new FileInputStream(file));
                            client.getTextOutData().writeUTF("*!sendfile: " + client.getClientName() + " " + target + " " +                                 file.getName() + " " + (int) file.length());
                            fileOut = new FileOutputStream(new File(downloadsPath + "/" + file.getName()));
                            System.out.println("Send length: " + file.length());
                            while ((count = fileStream.read(fileBuffer, 0, (int) Math.min(8192, file.length() - total))) ==         8192) {
                                    total += count;
                                    System.out.println("Sender count: " + count);
                                    client.getDLOutData().write(fileBuffer, 0, count);
                                    client.getDLOutData().flush();
                                    fileOut.write(fileBuffer, 0, count);
                            }
                            total += count;
                            System.out.println("Sender count: " + count);
                            System.out.println("Sender total: " + total);
                            //client.getDLOutData().write(fileBuffer, 0, count);
                            fileOut.write(fileBuffer, 0, count);

                            System.out.println("Sending done, eh?");
                            fileStream.close();
                            Thread.currentThread().interrupt();
                    } catch (Exception e) {
                            Platform.runLater(() ->Popups.startInfoDlg("Download Error", "Failed to send file!"));
                            e.printStackTrace();
                    }
            };

            return run;

    }

public static Runnable dlFile(MainScreenController sc, File file, long length) {
            Runnable run = () -> {
                    FileOutputStream fileOut = null;
                    try {
                            int total = 0;
                            int count;
                            byte[] fileBuffer = new byte[8192];
                            fileOut = new FileOutputStream(file);
                            System.out.println("DL length: " + length);
                            while ((count = sc.getClient().getDLInData().read(fileBuffer, 0, (int) Math.min(8192, length - total))) == 8192){
                                    total += count;
                                    System.out.println("DL count: " + count);
                                    fileOut.write(fileBuffer, 0, count);
                            }
                            total += count;
                            System.out.println("DL count: " + count);
                            System.out.println("DL total: " + total);
                            //fileOut.write(fileBuffer, 0, count);
                    } catch (IOException e) {
                            System.out.println("Failed to download file.");
                            e.printStackTrace();
                    } finally {
                            try {
                                    fileOut.flush();
                                    fileOut.close();
                            } catch (IOException e) {
                                    e.printStackTrace();
                            }
                            System.out.println("Download complete.");
                            Thread.currentThread().interrupt();
                    }
            };

            return run;

    }

If you have any ideas as to what the problem is, I'd love to hear them. I can also try and set up a Git for the entire project if you need to see more to help. Any help is appreciated, I'm still just beginning to learn java.

It looks like you're missing sending the tail end of the file. In your while loop on line 12, when you send the last part of the file, it will be less than 8192 bytes, unless the file was a direct multiple of 8192 bytes long. You're going to need to add in some code to handle this fence post problem. When you read in the final (file.length() % 8192) bytes, count is not equal to 8192, so the while loop does not execute. This means that the data is never written to the buffer.

I think if you did a comparison on the two pictures, the received one is missing the last (file.length() % 8192) bytes.

The typical idiom for reading through a file is:

byte[] fileBuffer = new byte[8192]; while ((count = fileStream.read(fileBuffer)) > 0) { // Do something with count bytes from the fileBuffer }

If a file has less number of bytes it gives that number of bytes and returns -1 at EOF .

The problem is you are not reading and sending the last part of your file, because of the condition in your while loop:

在此处输入图片说明

This condition do not allow the last part to be read from your source file and to be send. change the == 8192 part to > 0 to let the last part send.

Also you should change this condition in the dlFile method.

Good Luck.

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