Reputation: 377
I need to put a short and integer at the begging of a message that i am sending to a java server. The server is expecting to read a short (message id) then an integer (message length). I've read in the stackoverflow that NSMutableData is similar to java ByteBuffer.
I am trying to pack the message into NSMutableData then send it.
So this is what I have but is not working !.
NSMutableData *data = [NSMutableData dataWithLength:(sizeof(short) + sizeof(int))];
short msg_id = 2;
int length = 198;
[data appendBytes:&msg_id length:sizeof(short)];
[data appendBytes:&length length:sizeof(int)];
send(sock, data, 6, 0);
The server is using Java ByteBuffer to read in the received data. So the bytes coming in is:
32,120,31,0,2,0
which is invalid.
The correct value so the ByteBuffer can read them as .getShort() and .getInt()
0,2,0,0,0,-66
Upvotes: 1
Views: 1936
Reputation: 71018
You're basically putting stuff into the NSData object correctly, but you're not using it with the send
function correctly. First off, as dreamlax suggests, use NSMutableData's -initWithCapacity
initializer to get a capacity, not zeroed bytes.
Your data
pointer is a pointer to an Objective-C (NSData) object, not a the actual raw byte buffer. The send
function is a classic UNIX-y C function, and doesn't know anything about Objective-C objects. It expects a pointer to the actual bytes:
send(sock, [data bytes], [data length], 0);
Also, FWIW, note that endianness matters here if you're expecting to recover the multibyte fields on the server. Consider using HTONL
and HTONS
on the short and int values before putting them in the NSData buffer, assuming the server expects "network" byte order for its packet format (though maybe you control that).
Upvotes: 4
Reputation: 95335
I think your use of dataWithLength:
will give you an NSMutableData
object with 6 bytes all initialised to 0, but then you append 6 more bytes with actual values (so you'll end up with 12 bytes all up). I'm assuming here that short
is 2 bytes and int
is 4. I believe you want to use dataWithCapacity:
to hint how much memory to reserve for your data that you are packing.
As quixoto has pointed out, you need to use the bytes
method, which returns a pointer to the first byte of the actual data. The length
method will return the number of bytes you have.
Another thing you need to watch out for is endianness. The position of the most significant byte is dependent on the underlying architecture.
Upvotes: 1