包含整数和字符串表示的字节数组

时间:2013-08-29 08:43:32

标签: objective-c c byte bytearray bytebuffer

我正在为我的iPhone制作iOS套接字客户端。我需要通过tcp / ip发送一些字节。一般的想法是,我想在单个字节数组中存储多个值,以避免多次写入流。举个例子:

uint8_t buffer[1024]; // buffer to hold all data I'm sending

NSString *command = @"Broadcast"; // the actual message i want to send
int length = [command length]; // length of said message

现在,对于缓冲区数组中的前4个位置,我想要设置长度变量,而从4-13开始,我想放置实际的消息。我知道如何在服务器端解码它,但我无法弄清楚如何将这些数据放入缓冲区数组,所以我有一个数组包含我要发送的所有数据。

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:2)

请考虑以下代码:

// First, we get the C-string (NULL-terminated array of bytes) out of NSString.
const char *cString = [command UTF8String];

// The length of C-string (a number of bytes!) differs terribly from
// NSString length (number of characters! Unicode characters are 
// of variable length!).
// So we get actual number of bytes and clamp it to the buffer
// size (so if the command string occasionally gets larger than our
// buffer, it gets truncated).
size_t byteCount = MIN(BUFFER_SIZE - 4,
                       [command lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);

// Now we're using C type conversion to reinterpret the buffer as a
// pointer to int32_t. The buffer points to some memory, it's up to us
// how to treat it.
*(int32_t *)buffer = byteCount;

// And finally we're copying our string bytes to the rest of the buffer.
memcpy(buffer + 4, cString, byteCount); 

此代码中有一个警告 - 它使用主机字节顺序来存储uint32_t变量,因此如果您通过网络传递此缓冲区,通常最好使您的字节顺序固定(网络历史上使用大端,虽然现在大多数计算机都是小端的。)

要修复字节顺序,只需替换

*(int32_t *)buffer = byteCount;

*(int32_t *)buffer = htonl(byteCount);

在其他计算机上处​​理此缓冲区时,不要忘记转换字节顺序!

答案 1 :(得分:0)

您可以将其作为C字符串发送:

const char * cString = [command UTF8String];
length = strlen(cString);

for (int i = 0; i < length; ++i) {
    buffer[i + 4] = cString[i];
}

buffer[0] = length & 0xff;
buffer[1] = (length >> 8)  & 0xff;
buffer[2] = (length >> 16) & 0xff;
buffer[3] = (length >> 24) & 0xff;

答案 2 :(得分:0)

这不是生产代码,如果大小很大并且缺少错误检查,它会溢出。应该让你知道需要做什么。

const int SIZE = 64;
const int SIZE_OFFSET = 0;
const int MESSAGE_OFFSET = 4;


// Set up the buffer.
Byte buffer[SIZE];
for (int i = 0; i < SIZE; i++) {
    buffer[i] = 0;
}
uint8 *ptr; // Used to traverse data.

NSString *command= @"Broadcast";

// note: non ASCII characters, such as é,  will consume 2 bytes.
NSData *data = [command dataUsingEncoding:NSUTF8StringEncoding];
// uint32 ensures we get a 4 byte integer on non 32bit systems.
uint32 dataLength = [data length] ; // Number of bytes stored in data.

// Place dataLength into the first 4 elements of the buffer. Keep endianness in mind.
*ptr = &dataLength;
for (int8_t iterator = SIZE_OFFSET; iterator < sizeof(uint32) + SIZE_OFFSET; iterator++) {
    buffer[iterator] = ptr[iterator];
}

// todo, place data into buffer.