Хороший день для всех.Java ByteBuffer -> [NSData bytes] до UInt16
Я пишу клиент-серверное приложение на основе сокетов. Сервер написан с Java, клиент - с Objective-C на IOS SDK 7.
Мой сервер записывает данные на подключенный сокет со следующим кодом:
//Socket client = new ...;
DataOutputStream out = new DataOutputStream(client.getOutputStream());
// send package
String message = "pings"; // package body
byte bodySize = (byte) message.length();
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(2 + 2 + 1 + bodySize);
buffer.putShort((short) 16); // package ID (2 bytes)
buffer.putShort((short) 7); // package header (2 bytes, bitmask options)
buffer.put(bodySize); // calculate & put body size in 5th byte (1 byte)
buffer.put(message.getBytes()); // put the message to buffer (+5 bytes)
out.write(buffer.array()); // write to stream
out.close(); // close stream
Тогда я пытаюсь разобрать принятый NSData в клиенте Objective-C. Вот код:
- (UInt16)packageIdFromPackageHead:(NSData *)data {
const void *bytes = [data bytes];
UInt16 packageId;
memcpy(&packageId, bytes + 0, 2); // get first 2 bytes, it must be short = 16
return packageId;
}
Но в переменной «packageId» значение «4096». Что это? Где мое 16-значное десятичное значение?
Далее, я пытаюсь получить следующее значение, «заголовок пакета». Я написал следующий код:
UInt16 header;
memcpy(&header, bytes + 2, 2); // skip first 2 bytes, copy next 2 bytes, must be short = 7
Я получил огромное значение, 1792. Почему? Что означает это число? Я попробовал несколько смещений, +2, +3 - ничего. Я не могу получить правильное значение. Я пытался использовать некоторые преобразования в
header = CFSwapInt32BigToHost(header);
или
header = CFSwapInt32HostToBig(header);
Это приводит ни к чему - я 0 каждый раз после преобразования.
Далее, когда я попытался получить 5-й байт (он содержит нашу длину строки сообщения, вы помните). Вот код:
UInt8 bodySize;
memcpy(&bodySize, bytes + 4, 1); // get the 5th byte
я получил значение
'\x05'
И это правильно.
Я почти уверен, что значение входного NSData * верное. Здесь вы можете увидеть скриншот дампа памяти из Xcode:
Debug mode. Input NSData * memory dump
Где проблема? В коде сервера? Или в моем клиенте чтение кода? Пожалуйста, помогите, я потратил 2 дня, чтобы найти решение, и я все равно не смог его получить.
'memcpy (& packageId, bytes + 0, 2);' - где вы получаете 'bytes' из? –
И если вы NSLog объект NSData, вы получите шестнадцатеричный дамп, который вы можете проверить, чтобы определить, что вы получили. –
Да, моя ошибка. Bytes - 'const void * bytes = [data bytes]'. Я исправил описание моего вопроса. Благодарю. – George