Reputation: 595
I have created a server socket that accept a connection from a client, and when the connection is established an image is transferred to it using the OutputStream that write the bytes. My question is how can i check if the OutputStream has finished to write the bytes before close the socket connection, because sometimes not all the image is correctly transferred. This is the code that i'm using:
File photoFile = new File(getHeader); //getHeader is the file that i have to transfer
int size2 = (int) photoFile.length();
byte[] bytes2 = new byte[size2];
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(photoFile));
buf.read(bytes2, 0, bytes2.length);
buf.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
client.getOutputStream().write(bytes2, 0, size2); //client is the server socket
Thanks
Upvotes: 0
Views: 6031
Reputation: 310936
My question is how can i check if the OutputStream has finished to write the bytes before close the socket connection, because sometimes not all the image is correctly transferred
No, your problem is that you are assuming that read()
fills the buffer. The OutputStream
has finished writing when the write returns. Memorize this:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
This is the correct way to copy streams in Java. Yours isn't.
You are also assuming that the file size fits into an int,
and that the entire file fits into memory, and you are wasting both time and space reading the entire file (maybe) into memory before writing anything. The code above works for any size buffer from 1 byte upwards. I usually use 8192 bytes.
Upvotes: 6
Reputation: 69339
A common solution is to prefix the data with a number of bytes (say four) that describe the length of the data being sent.
The receiving server reads the first four bytes, calculates the length and knows when it has finished reading the file.
Upvotes: 3