0

I used the code from Here as below and got only half of the picture sent, could anybody tell me the reason? The code to get the size and read the size is too complex to me so I couldn't figure it out.

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();
}
} 

As @EJP commented,the most possible problem is that in the receive part,the inputStream.read(byte[] byteArray) can not fully load the byteArray. And if I use DataInputStream dis=new DataInputStream(inputStream) then call dis.readFully(byteArray) it would load the byteArray. Though I couldn't figure out the reason why inputStream won't work. Hopefully some one could show the reason, which would be well appreciated. The corrected code is as follow:

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();
}
}
Community
  • 1
  • 1
Kent Lee
  • 107
  • 4
  • 13

1 Answers1

0

Get rid of the byte array streams and do the ImageIO direct with the socket streams.

The problem is that you are assuming that read() fills the buffer, but if you do as above you will get rid of that read() completely anyway.

Sending the length is also pointless as you're closing them socket afterwards anyway. The end of stream is sufficient to delimit the image.

Get rid of the sleep as well. You don't need sleeps in network code.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I tried ImageIO before but I have to close the socket everytime to complete sending the image to server and I don't want to reconnect the server each time. Is there any way to fix this problem? – Kent Lee May 30 '15 at 19:02
  • Yes, don't assume that `read()` fills the buffer. Use `DataInputStream.readFully().` – user207421 May 30 '15 at 19:24
  • Instead of using `read(),` use `DataInputStream.readFully().` It does fill the array. – user207421 May 30 '15 at 20:19