IndexOutOfBoundsException при передаче файла через сокеты. срочный контроль передачи данных - PullRequest
1 голос
/ 10 марта 2020

Пожалуйста, помогите мне решить эту ошибку при передаче файла через сокеты:

java.lang.IndexOutOfBoundsException
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:326)
    at Client.getFile(Client.java:18)

Я реализовал клиент-серверное приложение для передачи файла по протоколу TCP. Сервер параллельный. Также необходимо реализовать контроль передачи с использованием срочных данных. Я не нашел решения на Java на Inte rnet.

Class Server:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    private ServerSocket serverSocket;

    public void start(int port) throws IOException {
        serverSocket = new ServerSocket(port);
        while (true)
            new ClientHandler(serverSocket.accept()).start();
    }

    public void stop() throws IOException{
        serverSocket.close();
    }

    private static class ClientHandler extends Thread {
        private Socket clientSocket;
        private DataOutputStream out;
        private FileInputStream in;

        public ClientHandler(Socket socket) {
            this.clientSocket = socket;
        }

        public void run() {
            try {
                out = new DataOutputStream(clientSocket.getOutputStream());
                out.writeInt((int) Prop.FILE_1.length());
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                in = new FileInputStream(Prop.FILE_1);
            } catch (IOException e) {
                e.printStackTrace();
            }

            while (true) {
                byte buf[] = new byte[512];
                int len = 0;
                try {
                    len = in.read(buf);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if(len == -1) {
                    break;
                }
                try {
                    out.write(buf, 0, len);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    out.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            /*try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }*/

        }
    }
}

Class Client:

import java.io.*;
import java.net.Socket;

public class Client {
    private Socket clientSocket;
    private FileOutputStream out;
    private DataInputStream in;

    public String getFile() throws IOException {
        int i = 0;
        int len;
        byte buf[] = new byte[512];
        Integer fileSize;
        fileSize = in.readInt();
        while (i < fileSize) {
            len = in.read(buf);
            if (len == -1) {
                break;
            }
            i += len;
            out.write(buf, 0, len);
            out.flush();
        }
        out.close();
        return in.readUTF();
    }

    public void startConnection(String ip, int port) throws IOException {
        clientSocket = new Socket(ip, port);
        out = new FileOutputStream(Prop.FILE_2);
        in = new DataInputStream(clientSocket.getInputStream());
    }

    public void stopConnection() throws IOException {
        in.close();
        out.close();
        clientSocket.close();
    }
}

Test

public class TestCS {
    @Test
            // (threadPoolSize = 3, invocationCount = 6, timeOut = 1000)
    public void givenClient1__whenServerResponds__thenCorrect() throws IOException {
        SoftAssert softAssert = new SoftAssert();
        Client client1 = new Client();
        client1.startConnection("127.0.0.1", 555);
        String file = client1.getFile();
        System.out.println(file);
        client1.stopConnection();
        softAssert.assertEquals(file, "First file!!!");
        softAssert.assertAll();
    }
}

1 Ответ

0 голосов
/ 10 марта 2020

Вы читаете InputStream неправильно. Логика c, которую вы пытаетесь поставить, уже доступна в методе DataInputStream.read(..). Все, что вам нужно сделать, это проверить, сколько байтов он прочитал из потока.

Измените ваше время l oop в Client вот так

while (i < fileSize) {
    // javadoc for below : - https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#read(byte[])
    len = in.read(buf);
    if(len<0) {
        break;
    }
    i += len;
    out.write(buf, 0, len);
    out.flush();
}

Примечание : я не проверял ваши логи c. Все, что я проверял и исправлял, это Исключение, которое вы получили.

Кроме того, обычно мы не читаем fileSize заранее. Обычно вы продолжаете чтение потока, пока не получите EOF (-1) из потока. Пожалуйста, проверьте также логи c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...