Упаковка данных Objective-C, используя NSMutableData? - PullRequest
1 голос
/ 20 ноября 2010

Мне нужно поставить короткое и целое число в начале сообщения, которое я отправляю на сервер Java.Сервер ожидает чтения короткого (идентификатор сообщения), а затем целого числа (длина сообщения).Я прочитал в стеке потока, что NSMutableData похож на Java ByteBuffer.

Я пытаюсь упаковать сообщение в NSMutableData, а затем отправить его.

Так вот, что у меня есть, но не работает!.

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

Сервер использует Java ByteBuffer для считывания полученных данных.Таким образом, поступающие байты:

32,120,31,0,2,0

, что недопустимо.

Правильное значение, чтобы ByteBuffer мог читать их как .getShort () и .getInt ()

0,2,0,0,0,-66

Ответы [ 2 ]

4 голосов
/ 20 ноября 2010

Вы в основном правильно помещаете вещи в объект NSData, но неправильно используете их с функцией send. Прежде всего, как предполагает dreamlax, используйте инициализатор NSMutableData -initWithCapacity, чтобы получить емкость, а не обнуляемые байты.

Ваш data указатель является указателем на объект Objective-C (NSData), а не фактическим необработанным байтовым буфером. Функция send является классической функцией UNIX-y C и ничего не знает об объектах Objective-C. Ожидается указатель на фактические байты:

send(sock, [data bytes], [data length], 0);

Также, FWIW, обратите внимание, что здесь важен порядок байтов, если вы ожидаете восстановить многобайтовые поля на сервере. Рассмотрите возможность использования HTONL и HTONS для значений short и int, прежде чем помещать их в буфер NSData, предполагая, что сервер ожидает «сетевой» порядок байтов для своего формата пакета (хотя, возможно, вы управляете этим).

1 голос
/ 20 ноября 2010

Я думаю, что использование dataWithLength: даст вам NSMutableData объект с 6 байтами, все инициализированы равными 0, но затем вы добавите еще 6 байтов с фактическими значениями (так что в итоге вы получите 12 байтов всего),Здесь я предполагаю, что short - это 2 байта, а int - это 4. Я полагаю, что вы хотите использовать dataWithCapacity:, чтобы намекнуть, сколько памяти резервировать для ваших данных, которые вы упаковываете.

Как указал quixoto, вам нужно использовать метод bytes, который возвращает указатель на первый байт фактических данных.Метод length вернет количество байтов, которое у вас есть.

Еще одна вещь, на которую нужно обратить внимание - это порядковый номер.Положение старшего байта зависит от базовой архитектуры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...