Я просто отправляю части изображения через сокет, используя 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() полностью в любом случае.

Отправка длины также не имеет смысла, так как вы потом закрываете их сокет. Конец потока достаточен для разделения изображения.

Избавьтесь от сна, а также. Вам не нужно спать в коде сети.

Другие вопросы по тегам