I am having a bit of trouble writing an android app that can communicate with my server to send and receive data. So the jist of it is that my server is written in Qt C++ and, of course, my app is written in java for android. A lot of complications have arisen from getting the socket data to be in the proper format for both sides to fully understand.

Well the problem I am having is that my client (java android) can connect to the server, send a small bit of data, and receive a response from the server. The server sends a decently large sized message of data converted to UTF-8 bytes.

QByteArray sendblock;
QDataStream out(&sendblock, QIODevice::WriteOnly);
out << (quint16)0;
char * data = msg.toUtf8().data();
out.writeRawData(data, msg.toUtf8().length());
out.device()->seek(0);
out << (quint16)(sendblock.size() - sizeof(quint16));
socket.write(sendblock);
socket.waitForBytesWritten();

The msg is a QString passed to the function.

On the client side, when the message is received, I have:

Log.d("connection", "Waiting for response");
short inSize;
inSize = in.readShort();
Log.d("connection", Integer.toString(inSize)); // the first 2 bytes are the size of the message
byte[] inData = new byte[inSize];//allocate space for the entire message
in.read(inData, 0, inSize); //read the entire message
String resp = new String(inData, 0, inSize, "UTF-8");//cast into a String
Log.d("connection", resp);

So the problem is that on differing instances of my program, the bytes cast to String differ in results.

The results of the Log.d printing the response is roughly 1445 letters (2890 bytes) of the string correctly formatted into a string, then the rest of the String ends up as "??" characters.

Rarely I get the entire message as expected with no "?" characters. Sometimes I get longer lengths of the message correctly cast as a String. Most of the time I just get 1445 of the letters correctly cast and the rest are "??" characters.

I have another client for windows computers (also written in Qt C++) that always gets the message complete and does not have this issue, so I am curious if there's something with android Strings and encoding that might be causing this problem. At first I thought it might have to do with memory allocation for the Strings, but I am pretty sure I have handled that properly with setting the sizes.

有帮助吗?

解决方案

As far as I can tell, the UTF-8 encoding and endian-ness of the byte count look correct. I think the only thing you are missing is you need to do your read in a while loop, since read is not guaranteed to fill the array. Try something like this. Check the return value of read to determine how many bytes are actually read and keep reading until you have 'inSize' bytes.

Log.d("connection", Integer.toString(inSize)); // the first 2 bytes are the size of the message
byte[] inData = new byte[inSize];//allocate space for the entire message

int count = 0;
while (count < inSize)
{
   int len = in.read(inData, count, inSize - count);
   count += len;
}
String resp = new String(inData, 0, inSize, "UTF-8");//cast into a String
Log.d("connection", resp);

You would need to extend this code and handle the case where len is -1 indicating the stream is closed.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top