Reputation: 489
I can't find a solution for this problem: I made a program on android to shot a picture (jpg format) and send it over the Bluetooth channel to an Embedded Windows XP pc. I also made the C++ application for Windows to receive the picture.
The communication is implemented using Bluetooth sockets.
In Android the app reads the file in chunks of 1024 bytes and write every chunk on the socket until the picture is finished.
On Windows side I read the bytes in chunck of 1024 bytes until the recv(...) function returns a value > 0.
The result is that on Android side it seems all the bytes are correctly read and sent, but on the Windows side I (almost) always receive only 70-80% of the bytes. I can even see the correct bytes received, as it is possible to visualize the jpg (missing bytes on the bottom part of the image are shown in grey). Only rarely I can receive the entire picture. Here I post the relevant part of code for the Android side:
String picturePath = "/sdcard/VERDE/PTR-0_15-31-24.jpg";
File picture = new File(picturePath);
if (picture.exists())
{
Log.d(TAG, "File " + picture.getAbsolutePath() + " exists!");
try
{
FileInputStream fis = new FileInputStream(picture);
ostream = socket.getOutputStream();
byte[] buf = new byte[1024];
int read = 0;
int totBytes = 0;
while ((read = fis.read(buf)) != -1)
{
totBytes = totBytes + read;
ostream.write(buf, 0, read);
Log.d(TAG, "Image - Read: " + read + " - Total "
+ totBytes + " bytes!");
}
ostream.flush();
ostream.close();
fis.close();
} catch (UnknownHostException ex)
{
System.out.println(ex.getMessage());
} catch (IOException ex)
{
System.out.println(ex.getMessage());
}
} else
{
Log.d(TAG, "File " + picture.getAbsolutePath()
+ " does not exist!");
}
This is the relevant part of code of the C++ application:
if (_outFile != NULL)
{
_outFile.open(result.c_str(), ofstream::binary); //"pic.jpg"
cout << "File opened!" << endl;
} else
{
cout << "Can't open file!" << endl;
}
while ((received = recv(client, buf, sizeof(buf), 0)) > 0)
{
cout << "R:" << received << " ";
if (received > 0)
{
totalBytes += received;
if (_outFile.is_open())
{
_outFile.write(buf, received);
cout << " (Total: " << totalBytes << " B)" << endl;
} else
cout << "Error in recv() function, received bytes = "
<< received << endl;
} else
cout << "R:" << received << " ";
}
I've seen tens of blogs and posts on this topic but noone seems to have a similar problem! Please, help me if you have any idea!
Thanks!
Upvotes: 0
Views: 1079
Reputation: 489
I found the problem in my code!
I thought it was on the receiveing side and indeed it was on the transmitting Android code.
The problem was that the socket.close() function was called before all the bytes were actually transferred!
I realized that trying first with a Thread.CurrentThread().sleep(2000) before closing the socket, but this is not optimized.
The best way, imho, is to implement a small protocol of control data exchange between client and server in order to ensure the picture is completely transferred (here a pseudocode example):
if (received bytes == picLengthInBytes)
reply("pictureOK")
Upvotes: 0
Reputation: 55
I have exactly the same problem (but instead of bloutoth with normal sockets). Did you already find anything useful how to fix this? I tried everything and still get the same error.
Else I think I found out what the problem is, but I don't know to to solve this. In the last step, when there are <1024 Bytes transferred, I assigned buffer to a string, and then cout the length of the string, which was smaller than the bytes received in the last step. I think somehow he is not receiving everything in the last step, when the data <1024 Bytes
Upvotes: 0