Reputation: 41
I want send a large file from Android to server through socket, but file received by server is incomplete.
Code on android:
Socket client = new Socket(ipStr, 4444);
OutputStream outputStream = client.getOutputStream();
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
byte[] buffer = new byte[512];
byte[] sendLen = getBytes(file.length(), true);
outputStream.write(sendLen);
outputStream.flush();
int count;
while ((count = fileInputStream.read(buffer)) > 0)
{
outputStream.write(buffer, 0, count);
}
outputStream.flush();
bufferedInputStream.close();
outputStream.close();
client.close();
Code on server:
byte[] recvHead = new byte[8];
inStream.read(recvHead, 0, 8);
long recvLength = getLong(recvHead, false);
FileOutputStream file = new FileOutputStream(fileName, false);
byte[] buffer = new byte[8192];
int count = 0;
while (count < recvLength) {
int n = inStream.read(buffer);
if(n == -1)
break;
file.write(buffer, 0, n);
count += n;
}
But server will blocking in read(buffer) (the file android sended is about 30M).
Here is the strange thing: When I add an output to file while sending file , server can work properly.
FileOutputStream file2 = new FileOutputStream("/sdcard/testfile" , false);
while ((count = fileInputStream.read(buffer)) >= 0)
{
outputStream.write(buffer, 0, count);
outputStream.flush();
file2.write(buffer, 0, count);
file2.flush();
}
Anyone can help me with this? Thank you!
Upvotes: 4
Views: 1202
Reputation: 310860
You can't assume you read the 8 length bytes like that. You could have read as little as one byte into the length array. I would use DataInputStream.readLong() for that, and DataOutputStream.writeLong() to write it. Or, as you are closing after one file, get rid of the length word altogether and just read until EOS.
The rest of the code looks OK. If the receiver blocks in read() the data is still coming, and the sender is still sending.
Upvotes: 1