SendClientBinary - client values representation confusion

72 views
Skip to first unread message

anb8

unread,
Jul 11, 2013, 4:51:18 PM7/11/13
to quick...@googlegroups.com
Sorry if this is a basic binary math knowledge that I lost over the past few years, but I have a great confusion in the way my buffer is being transmitted from the server to the client.

I have a buffer of bytes that are in full 0-255 range, therefore some of the values appear negative as byte is signed in Java (news to me, Java noob so far). I am transmitting this array of bytes to the client by setting the DataMode to Binary and then calling ClientHandler.sendClientBinary. My iOS application then receives the data to an unsinged byte array, however, when I look at the values in the memory, each negative value received from Java server seems to span 2 bytes - e.g. value of -71 (0xB9) in Netbeans looks in XCode memory view as 0xC2 0xB9. Similary -67 (0xBD) in Netbeans appears as 0xC2 0xBD in XCode. For positive values (0-127 in Java signed byte array) the values are displayed correctly in XCode and each byte from server spans 1 byte in client.
Really lost on what is going on here, any help much appreciated.

Fabio Ferreira

unread,
Jul 12, 2013, 9:42:35 AM7/12/13
to quick...@googlegroups.com
Java uses signed variables. The problem is that signed variables are negative if the most significant bit is "1". For example this byte 10001001 is a negative number for Java.

The solution is to use char values, these are unsigned.

I used this way in quickserver : in data receive event, I converted the string message into a char array (String.toCharArray()) and later I manipulated these individuals values.

anb8

unread,
Jul 12, 2013, 9:50:30 AM7/12/13
to quick...@googlegroups.com
Thanks, Fabio.
I have a function that returns values to a signed byte array that I have to send over TCP socket to an iOS app. However, the quickserver SendClientBinary() method only supports byte array as input parameter, therefore I cannot use the char array which as you mentioned is unsigned.

I think it should not be a problem that SendClientBinary sends the values from signed byte array where some of the values are negative. The problem is the receiving part in iOS sees negative values as 2-byte values instead of 1-byte value. Is it possible that SendClientBinary does some kind of math on negative values and converts them before sending over the network?

Fabio Ferreira

unread,
Jul 12, 2013, 10:06:22 AM7/12/13
to quick...@googlegroups.com
The process of converting to a char array is only for decoding and processing the data, for example I receive mesages that have many values inside the array and these values are composed of 3-4 bytes so I have to extract these byte, group them and analize bit to bit. But if I need to send the data I cast the char array to byte array before sending.

I think you have to use a software like HERCULES or similar to receive in a computer the data from quickserver and analize it.

anb8

unread,
Jul 12, 2013, 4:43:04 PM7/12/13
to quick...@googlegroups.com
I am starting to go mad from this.
I have an array of bytes where some of the values are negative. Then I copy the whole array to a new char array and mask upper byte of each char in the array with zeroes, so I am left with lower byte holding the correct value. Now I want to pass this char array to some of the ClientHandler send functions. When I set DataMode to Byte and send the char array converted to String (myCharData.toString() ) I get just a few characters in the client. If I want to send in DataMode.BINARY then I have to use clientHandler.sendClientBinary, however, this method only accepts byte array as input while I have a char array with correct values which cannot be converted to byte array. If I just create byte array again and copy the values from char array into it, I get negative values again and those are transmitted as two-byte values to TCP client.

Is there a way how to use a char array (with some cast??) as input to sendClientBinary() method? Or should I use a completely different method to transfer the byte array with negative values??

Fabio Ferreira

unread,
Jul 12, 2013, 5:09:54 PM7/12/13
to quick...@googlegroups.com
I use "sendClientBytes()" method of teh clientHandler. Try with that

anb8

unread,
Jul 13, 2013, 2:13:53 AM7/13/13
to quick...@googlegroups.com

On Friday, July 12, 2013 11:09:54 PM UTC+2, Fabio Ferreira wrote:
I use "sendClientBytes()" method of teh clientHandler. Try with that

And how do you pass byte array to sendClientBytes? It only accepts String and when I call myCharArray.toString() I am definitely not receiving correct array in the receiver.



 

Akshath

unread,
Jul 13, 2013, 2:20:04 AM7/13/13
to quick...@googlegroups.com
as Fabio says.. you should be able to use sendClientBytes().. let me give you a bit of detail

char mydata[] = "test".toCharArray();//replace this with your data

//now convert this to String so you can use sendClientBytes() method.. s
String dataToSend = new String(mydata);

//make sure your data mode for out is DataMode.BYTES
//now send the data out
handler.sendClientBytes(dataToSend);

Also you could convert your byte data into base64 format for transmission.. and can do base64 decoding at client end.. this way you will be sure your byte data arrives without any change across os platforms.

anb8

unread,
Jul 13, 2013, 5:19:23 PM7/13/13
to quick...@googlegroups.com
Thansk, Akshath.
I have done this:
//get byte array with my values
byte image[] = (byte[])classX.GetByteArrayValues();

//convert byte array to char array, so all the values will be positive 0...255
char imageCh[] = new char[image.length];
for  (int ij = 0; ij < image.length; ij++)
{
     imageCh[ij] = (char) image[ij];
     if (imageCh[ij] > 255)
         imageCh[ij] &= 0xFF;
}

//set DataMode to BYTE
clientH.setDataMode(DataMode.BYTE, DataType.OUT);
//convert char array to string
String b = new String(imageCh);
//send string with sendClientBytes
clientH.sendClientBytes(b);

However, the result in the receiving application is the same (negative values are 2 bytes). I am starting to think it's a problem of the receiving application where I first read the input stream into a string with NSASCIIStringEncoding and then when I want to retrieve the byte portion of this string where my data payload is located, I read the bytes from the string with NSUTF8StringEncoding. As I just realized this encoding is variable in width so that could explain why values of  128-255 are represented by two bytes.

anb8

unread,
Jul 14, 2013, 4:27:31 AM7/14/13
to quick...@googlegroups.com
Problem solved.
The solution is in my iOS app where I get the binary portion of my data payload from NSData buffer of bytes instead of the NSString to which I copy the byte buffer in order to search for certain strings as rest of the data is not binary values. Converting those bytes to string first with some encoding and then back to bytes with other encoding was the problem.
I can be perfectly sending signed bytes from Quickserver in DataMode.BINARY and sendClientBinary(byte[]) method.

Thanks both Fabio and Akshath for your help.
Reply all
Reply to author
Forward
0 new messages