views:

31

answers:

2

I'm having trouble communicating position coordinates to a set of motors I have connected on the network. I can send a string just fine, and receive text back from the motor, but I can't seem to send it an int value.

Using NSlog I have determined that the actual value I'm sending is correct, however I suspect my method of sending it via the output stream is wrong. Any ideas?

My code for sending a 64bit int value:

uint64_t rawInt = m1; 
rawInt <<= 16; 
rawInt |= m2;
NSData *buffer = [NSData dataWithBytes: &rawInt length:8];
[outputStream write: [buffer bytes] maxLength:[buffer length]];
+1  A: 

You're probably seeing an endianness problem. Intel CPUs are little-endian, meaning that the least significant byte in a multi-byte value is stored first, the most significant byte last. Reading an 8-byte number from memory and putting it on the network without doing anything will cause the bytes to go out in that order.

Most network protocols (including all internet protocols) expect big-endian data, so the most significant byte appears on the network first and the least significant byte last. Does your network protocol expect that?

Graham Lee
+4  A: 

Well, your codes looks kind of funny. Anyway, for sending a binary integer over the network, you have to know the endianess: The receiver either expects little or big endian integers.

Here's the code for both:

uint64_t myInt = 42;

uint64_t netInt = CFSwapInt64HostToLittle(myInt); // use this for little endian
uint64_t netInt = CFSwapInt64HostToBig(myInt);    // use this for big endian

[outputStream write:(uint8_t*)&netInt maxLength:sizeof(netInt)];
Nikolai Ruhe
The code above gives the warning: "warning: passing argument 1 of 'write:maxLength:' from incompatible pointer type".
Despite the warning, the code works. My endianess was the opposite of what it should be. Thanks!
Added cast to remove warning.
Nikolai Ruhe