M
M
mrRobot19832016-10-10 11:52:47
Computer networks
mrRobot1983, 2016-10-10 11:52:47

What is the error(java/socket/file transfer)?

Good afternoon everyone! I am writing an application that sends files from the client to the server. With one file everything works fine, but when several files are sent, an exception is generated

Exception in thread "main" java.lang.NegativeArraySizeException
at double2.code.code1.Receiver.receiveFile(Receiver.java:45)
at double2.code.code1.Receiver.main(Receiver.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Server code:
public class Sender {

static ServerSocket server;
static final int PORT = 6666;
static ArrayList<Socket> sockets;
static String basePath = "C:\\as\\server";
public static void main(String[] args) throws IOException {
    server =new ServerSocket(PORT);
    sockets = new ArrayList<Socket>();

    String fileName ="111.jpg";

    ArrayList<String>locations = new ArrayList<String>();
    locations.add(fileName);
    locations.add("1.jpg");


    Socket socket = server.accept();

    Sender.send(socket,locations);

    socket.close();

}
static void sendFileNames(Socket socket,ArrayList<String>fileNames) throws IOException {
    DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
    dataOutputStream.writeInt(fileNames.size());//отправляем размер
    for (String name:fileNames){
        dataOutputStream.writeUTF(name);
    }
}
public static  void send(Socket socket,ArrayList<String> fileNames) throws IOException {
    FileInputStream fileInputStream = null;
    BufferedInputStream bufferedInputStream = null;

    DataOutputStream outputStream = null;
    try {
        System.out.println("Waiting for receiver...");
            try {
                    System.out.println("Accepted connection : " + socket);
                sendFileNames(socket,fileNames);
                for(String fileName:fileNames) {
                    File file = new File(basePath + "\\"+fileName);
                    byte[] byteArray = new byte[(int) file.length()];
                    System.out.println("lol");
                    outputStream = new DataOutputStream(socket.getOutputStream());
                    outputStream.writeLong(file.length());//TODO
                    System.out.println("lol");
                    fileInputStream = new FileInputStream(file);
                    bufferedInputStream = new BufferedInputStream(fileInputStream);
                    bufferedInputStream.read(byteArray, 0, byteArray.length); // copied file into byteArray

                    System.out.println("Sending " + fileName + "( size: " + byteArray.length + " bytes)");
                    outputStream.write(byteArray, 0, byteArray.length);
                    outputStream.flush();                                        //flushing socket
                    System.out.println("Done.");
                }
                }
                finally {
                    if (bufferedInputStream != null) bufferedInputStream.close();
                    if (outputStream != null) bufferedInputStream.close();
                    if (socket!=null) socket.close();
                }       
        } catch (IOException e) {

            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally {
            if (server != null) server.close();
        }
}
}

customer code:
public class Receiver {

static Socket socket;
static final int PORT = 6666;
static final String IP = "127.0.0.1";
static DataInputStream dim;
static String basePath = "C:\\as\\client";
public static void main (String [] args ) throws IOException {

    socket = new Socket(IP,PORT);

    receiveFile();

    System.out.println("yeeee");

}
static ArrayList<String>readFileNames() throws IOException {
    ArrayList<String>res = new ArrayList<String>();
    DataInputStream din = new DataInputStream(socket.getInputStream());
    int lenght = din.readInt();
    for(int i = 0;i<lenght;i++){
        String name = din.readUTF();
        res.add(name);
    }
    return res;
}
public static void receiveFile() throws IOException {
    int bytesRead = 0;
    int current = 0;
    FileOutputStream fileOutputStream = null;
    BufferedOutputStream bufferedOutputStream = null;
    try {
        ArrayList<String> locations = readFileNames();

        for (String location:locations) {
            dim = new DataInputStream(socket.getInputStream());
            long res = dim.readLong();
            System.out.println("res "+res);
            byte[] byteArray = new byte[(int) res + 1];
            System.out.println("sizze" + res);

            System.out.println("Please wait downloading file");

            DataInputStream inputStream = new DataInputStream(socket.getInputStream());
            File f = new File(basePath + "\\" + location);
            fileOutputStream = new FileOutputStream(f);

            System.out.println(f.createNewFile());

            //TODO !!!!!!!!!!!
            bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            bytesRead = inputStream.read(byteArray, 0, byteArray.length);                    //copying file from socket to byteArray

            current = bytesRead;
            System.out.println("hah");
            do {
                bytesRead = inputStream.read(byteArray, current, (byteArray.length - current));
                System.out.println(current);
                if (current == res)
                    break;
                if (bytesRead >= 0) current += bytesRead;
            } while (bytesRead > -1);
            bufferedOutputStream.flush();
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (fileOutputStream != null) fileOutputStream.close();
        if (bufferedOutputStream != null) bufferedOutputStream.close();
    }
}
}

By logging, I saw that some left value of the file size is transmitted 2 times, and most likely an error is generated because of this. Please tell me how to solve this problem.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
E
Evgeny Kornachev, 2016-10-10
@mrRobot1983

long res = dim.readLong();
            System.out.println("res "+res);

            //здесь ты приводишь long к int, и может произойти переполнение,
            // и размерность массива будет отрицательной. Из-за этого вылетает эксепшн
            byte[] byteArray = new byte[(int) res + 1];

the second time you pass the length of the array that the server read
and again you cut the length by limiting the int
File file = new File(basePath + "\\"+fileName);
//вот здесь ты обрезал получаемою длину файла, и от потока требуешь в будущем прочитать данные в этот массив
//но читаешь ты только кусок
//опять же здесь ты можешь снова получить отрицательное значение размерности массива
byte[] byteArray = new byte[(int) file.length()];

//и во второй раз ты передаешь длину ОБРЕЗАННОГО МАССИВА который в реальности смог прочитать здесь
bufferedInputStream.read(byteArray, 0, byteArray.length); // copied

do not store the data in an array, pass the length as a long (or don’t pass it at all, there is no need for it), and then in the loop read byte by byte through read () (the method returns int - and as soon as it returns -1, then the data is over) and immediately write to the file .

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question