Answer the question
In order to leave comments, you need to log in
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)
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();
}
}
}
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();
}
}
}
Answer the question
In order to leave comments, you need to log in
long res = dim.readLong();
System.out.println("res "+res);
//здесь ты приводишь long к int, и может произойти переполнение,
// и размерность массива будет отрицательной. Из-за этого вылетает эксепшн
byte[] byteArray = new byte[(int) res + 1];
File file = new File(basePath + "\\"+fileName);
//вот здесь ты обрезал получаемою длину файла, и от потока требуешь в будущем прочитать данные в этот массив
//но читаешь ты только кусок
//опять же здесь ты можешь снова получить отрицательное значение размерности массива
byte[] byteArray = new byte[(int) file.length()];
//и во второй раз ты передаешь длину ОБРЕЗАННОГО МАССИВА который в реальности смог прочитать здесь
bufferedInputStream.read(byteArray, 0, byteArray.length); // copied
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question