I’ve implemented an Android application that takes a picture with the SP camera and sends it over a socket to the server.
I’m using the following (JAVA) code to read the image file stored locally and send it in successive chunks over the socket:
FileInputStream fileInputStream = new FileInputStream( "my_image_file_path" );
int nRead;
byte[] data = new byte[16384];
try {
while( (nRead = fileInputStream.read(data, 0, data.length)) != -1 ){
networkOutputStream.write( data, 0, nRead );
}
} catch( IOException e ){
e.printStackTrace();
}
fileInputStream.close();
And the following (C/C++) code to read it and store it on the server:
char newbuffer[MAX_BUF_SIZE];
int checkOperation;
ofstream outfile( "image_file_path".c_str(), ofstream::binary );
do{
checkOperation = read( clientSocketDescriptor, newbuffer, sizeof(newbuffer) );
if( checkOperation < 0 ){
cout << "Error in recv() function, received bytes = " << checkOperation << endl;
exit(1);
}else if (checkOperation != 0 ){
/*
* some data was read
*/
cout << endl << "READ Bytes: " << checkOperation << endl;
outfile.write( newbuffer, checkOperation );
/*
* emptying buffer for new incoming data
*/
for(int i = 0; i < sizeof(newbuffer); i++){
newbuffer[i] = 0;
}
}
}while( checkOperation =! 0 );
outfile.close();
The Android client application seems to write correctly all the bytes in the socket, and successfully exits from the while loop.
However the server code gets stuck in the last iteration of its while loop, and isn’t able to continue execution.
- Why can’t the server read the
EOF? - Is my code for sending the image or reading it not correct?
Thanks in advance for any kind of help, since I’m really stuck!
You’re not closing the
networkOutputStream, so the C++ code doesn’t know you’re finished.Either you need to close the output stream – which is only viable if you don’t need to send any more data on it, obviously – or you need to include some metadata in the protocol to either indicate before you start writing how much more data there is, or include something afterwards as a “done” indicator. Generally I prefer a length prefix – it’s much simpler than having to worry about escaping if the “done” indicator appears naturally in data.
A half-way house is to repeatedly say “here’s a chunk of data length X” and then an “I’m done, no more chunks” message (which could be “here’s a chunk of data length 0” for example). This way you don’t need to know the total length beforehand.