3

我正在为我的 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 开始,我想放置实际消息。我知道如何在服务器端对其进行解码,但我不太清楚如何将这些数据放入缓冲区数组,所以我有一个包含我想要发送的所有数据的数组。

非常感谢任何帮助!

4

3 回答 3

2

Consider the following code:

// 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); 

There's a caveat in this code - it uses host byte order to store uint32_t variable, so if you're passing this buffer over network, it's generally a good idea to make your byte order fixed (networking historically employs big-endianness, though most of the computers are nowadays little-endian).

To fix the byte order just replace the line

*(int32_t *)buffer = byteCount;

with

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

And don't forget to convert byte ordering back when processing this buffer on other computer!

于 2013-08-29T09:03:47.733 回答
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.
于 2013-08-29T10:12:08.817 回答
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;
于 2013-08-29T08:56:01.027 回答