Я просто отправляю части изображения через сокет, используя Java
Я использовал код отсюда, как показано ниже, и получил только половину изображения, кто-нибудь может сказать мне причину? Код, чтобы получить размер и прочитать размер слишком сложен для меня, поэтому я не мог понять это.
public class Send {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost", 13085);
OutputStream outputStream = socket.getOutputStream();
BufferedImage image = ImageIO.read(new File("C:\\Users\\Jakub\\Pictures\\test.jpg"));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", byteArrayOutputStream);
byte[] size = ByteBuffer.allocate(4).putInt(byteArrayOutputStream.size()).array();
outputStream.write(size);
outputStream.write(byteArrayOutputStream.toByteArray());
outputStream.flush();
System.out.println("Flushed: " + System.currentTimeMillis());
Thread.sleep(120000);
System.out.println("Closing: " + System.currentTimeMillis());
socket.close();
}
}
public class Receive {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(13085);
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
System.out.println("Reading: " + System.currentTimeMillis());
byte[] sizeAr = new byte[4];
inputStream.read(sizeAr);
int size = ByteBuffer.wrap(sizeAr).asIntBuffer().get();
byte[] imageAr = new byte[size];
inputStream.read(imageAr);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageAr));
System.out.println("Received " + image.getHeight() + "x" + image.getWidth() + ": " + System.currentTimeMillis());
ImageIO.write(image, "jpg", new File("C:\\Users\\Jakub\\Pictures\\test2.jpg"));
serverSocket.close();
}
}
Как прокомментировал @EJP, наиболее вероятная проблема заключается в том, что в принимающей части inputStream.read(byte[] byteArray) не может полностью загрузить byteArray. И если я использую DataInputStream dis=new DataInputStream(inputStream), то вызову dis.readFully (byteArray) он загрузит byteArray. Хотя я не мог понять причину, почему inputStream не будет работать. Надеюсь, кто-то мог показать причину, которая была бы хорошо оценена. Исправленный код выглядит следующим образом:
public class Send {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost", 13085);
OutputStream outputStream = socket.getOutputStream();
BufferedImage image = ImageIO.read(new File("test.jpg"));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", byteArrayOutputStream);
byte[] size = ByteBuffer.allocate(4).putInt(byteArrayOutputStream.size()).array();
outputStream.write(size);
outputStream.write(byteArrayOutputStream.toByteArray());
outputStream.flush();
System.out.println("Flushed: " + System.currentTimeMillis());
Thread.sleep(120000);
System.out.println("Closing: " + System.currentTimeMillis());
socket.close();
}
}
public class Receive {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(13085);
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream=new DataInputStream(inputStream);
System.out.println("Reading: " + System.currentTimeMillis());
byte[] sizeAr = new byte[4];
dataInputStream.read(sizeAr);
int size = ByteBuffer.wrap(sizeAr).getInt();
byte[] imageAr = new byte[size];
dataInputStream.readFully(imageAr);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageAr));
System.out.println("Received " + image.getHeight() + "x" + image.getWidth() + ": " + System.currentTimeMillis());
ImageIO.write(image, "jpg", new File("received.jpg"));
serverSocket.close();
}
}
1 ответ
Избавьтесь от потоков байтового массива и выполните ImageIO
прямой с сокетом потоков.
Проблема в том, что вы предполагаете, что read()
заполняет буфер, но если вы сделаете, как указано выше, вы избавитесь от этого read()
полностью в любом случае.
Отправка длины также не имеет смысла, так как вы потом закрываете их сокет. Конец потока достаточен для разделения изображения.
Избавьтесь от сна, а также. Вам не нужно спать в коде сети.