Я столкнулся с проблемой извращения после того, как вложил свои руки в старый унаследованный проект.Проект состоит из приложения Java и приложения c ++, которые взаимодействуют с сокетами.Оба приложения предназначены для работы в кроссплатформенных средах, поэтому я был бы рад сделать код как можно более универсальным.
В итоге я переписал части логики связи, поскольку в предыдущей реализации были некоторые проблемы синостранные персонажи.Теперь я столкнулся с проблемой с порядком байтов, которую, я надеюсь, кто-нибудь сможет мне объяснить.
Программное обеспечение Java записывает сообщения в сокет с помощью OutputStreamWriter, используя кодировку UTF-16LE, следующим образом.
OutputStream out = _socket.getOutputStream();
outputWriter = new OutputStreamWriter(new BufferedOutputStream(out), "UTF-16LE");
// ... create msg
outputWriter.write(msg, 0, msg.length());
outputWriter.flush();
Программа c ++ получает сообщение символ за символом следующим образом:
char buf[1];
std::queue<char> q;
std::u16string recUtf16Msg;
do {
int iResult = recv(socket, buf, 1, 0);
if (iResult <= 0)
break; // Error or EOS
for (int i = 0; i < iResult; i++) {
q.push(buf[i]);
}
while (q.size() >= 2) {
char firstByte = q.front();
q.pop();
char secondByte = q.front();
q.pop();
char16_t utf16char = (firstByte << (sizeof(char) * CHAR_BIT)) ^
(0x00ff & secondByte);
// Change endianness, if necessary
utf16char = ntohs(utf16char);
recUtf16Msg.push_back(utf16char);
}
// ... end of message check removed for clarity
} while (true);
Теперь проблема, с которой я действительно сталкиваюсь, заключается в том, что приведенный выше код действительно работает, но я не совсем уверен, почему.Сторона c ++ написана для получения сообщений, которые используют сетевой порядок байтов (с прямым порядком байтов), но кажется, что java отправляет данные, используя кодировку с прямым порядком байтов.
На стороне c ++ мы даже используем функцию ntons для изменения порядка байтов натот, который требуется на хост-машине.В соответствии со спецификацией, я понимаю, что hton должен выполнять порядок байтов подстановки, если платформа хоста использует порядок байтов с прямым порядком байтов.Однако ntonhs на самом деле меняет порядковый номер получаемых символов с прямым порядком байтов, который заканчивается как большой порядок байтов и программное обеспечение работает безупречно.
Может быть, кто-то может указать, что именно происходит?Я случайно переключаю байты уже при создании utf16char?Почему htons заставляет все работать, а кажется, что он действует совершенно противоположно документации?Для компиляции я использую Clang с libc ++.
Я упустил части кода для ясности, но вы должны получить общее представление.Кроме того, я знаю, что использование очереди и динамического массива, возможно, не самый эффективный способ обработки данных, но он чистый и работает достаточно хорошо для этой цели.