Как предотвратить повреждение файла при передаче через локальную сеть через сокеты? - PullRequest
0 голосов
/ 14 октября 2019

Я работаю над школьным проектом, где хочу создать персональный сервер хранения. В настоящий момент я пытаюсь передать файл с клиентского компьютера на сервер. Однако при тестировании этого с изображением файл частично отправляет, прежде чем он повреждается. Пожалуйста, помните, что я довольно новый программист и что мои технические знания могут быть чем-то ограниченным.

Я использую байтовый массив через DataOutputStream для передачи файла. Я хочу использовать этот метод, так как он должен работать для любого типа файла. Я пытался установить размер буфера на точный размер файла и больше, но ни один из них не работал.

Сервер:

public void run() {
            try {
                System.out.println("ip: " + clientSocket.getInetAddress().getHostAddress());

                out = new DataOutputStream(clientSocket.getOutputStream());
                in = new DataInputStream(clientSocket.getInputStream());

                in.read(buffer, 0, buffer.length);

                fileOut = new FileOutputStream("X:\\My Documents\\My 
                Pictures\\gradient.jpg");

                fileOut.write(buffer, 0, buffer.length);
                in.close();
                out.close();
                clientSocket.close();

         } catch (IOException ex) {
                System.out.println(ex.getMessage());
            }
        }

Клиент:

 public void startConnection(String ip, int port) {
        try {
            clientSocket = new Socket(ip, port);
            out = new DataOutputStream(clientSocket.getOutputStream());
            in = new DataInputStream(clientSocket.getInputStream());

            x = false;
            Path filePath = Paths.get("C:\\Users\\georg\\Documents\\gradient.jpg");
            buffer = Files.readAllBytes(filePath);
            Thread.sleep(3000);
            //Files.write(filePath, buffer);
            //out.write(buffer,0,buffer.length);
            x = true;
            sendMessage(buffer);


        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        } catch (InterruptedException ex) {
            Logger.getLogger(PCS_Client.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public byte[] sendMessage(byte[] buffer) {
        if (x==true){
        try {
            out.write(buffer,0,buffer.length);

        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }

    }
        return null;
    }

Вот сравнение файлов, которые я пытался отправить, и файлов, которые я получаю: https://imgur.com/gallery/T7nUUJT

Любопытно, что при отправке одноцветного изображения на сервере получается одноцветное изображение. Я полагаю, что проблема здесь может заключаться в сроках выполнения кода, однако я не уверен и не знаю, как это исправить.

1 Ответ

1 голос
/ 14 октября 2019

Проблема в коде вашего сервера, в этой строке:

in.read(buffer, 0, buffer.length);

Вы ожидаете прочитать все данные одновременно, но если вы прочитаете документ, вы найдете это:

public final int read (byte [] b, int off, int len) выбрасывает IOException

Считывает до len байтов данных из содержащегося входного потока в массив байтов. Предпринята попытка прочитать столько же, сколько и байтов, но можно прочитать меньшее число, возможно, ноль. Количество фактически прочитанных байтов возвращается как целое число.

Важной частью является Считывание до len байтов данных.

Вы должны использовать возвратЗначение read и вызовите его read несколько раз, пока больше нечего читать.

...