Я запускаю сервер с использованием сокетов в C ++. После подключения к клиенту (для этого используется netcat), у меня появляется функция, которая читает то, что отправил клиент, и пытается его проанализировать.
Структура:
struct m
{
uint8_t m1;
}
struct str
{
uint64_t a;
uint32_t b;
uint32_t c;
}
Функция:
int f(int x){
char s[1024];
if (read(x,s,sizeof(s)-1) > 0){
m *msg = reinterpret_cast<m *>(s);
if(msg->m1 == 0)
{
str *st = reinterpret_cast<str *>(s+1);
uint64_t a = htonll(st->u);
uint32_t b = htonl(st->v);
uint32_t c = htonl(st->w);
std::cout<<a<<" "<<b<<" "<<c<<std::endl;
}
else
{....
}
}
редактировать:
uint64_t htonll(uint64_t value)
{
// The answer is 42
static const int num = 42;
// Check the endianness
if (*reinterpret_cast<const char*>(&num) == num)
{
const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32));
const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL));
return (static_cast<uint64_t>(low_part) << 32) | high_part;
} else
{
return value;
}
}
В этом конкретном случае не должно быть проблем с заполнением. Я могу правильно разобрать и достичь в пределах *msghead == '0'
если условие. Однако я не получаю ожидаемых значений a, b and c
, Я пробовал много случаев, но значения не имеют особого смысла.
Как я тестирую:
echo -n -e '\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01' | nc localhost 9000
В идеале я должен получить вывод как 1 1 1, но я получаю 0 0 0.
Кроме того, если я изменю это на
echo -n -e '\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01' | nc localhost 9000
я получил 1 0 0
Я не уверен, что что-то не так с порядком байтов, который я могу исправить, но в любом случае, похоже, есть и другая проблема.
Вот проблема:
uint64_t a = htons(st->u);
uint32_t b = htons(st->v);
uint32_t c = htons(st->w);
Если вы читаете эта ссылка POSIX вы увидите, что htons
для 16-битный целые числа и htonl
для 32-битных целых чисел. Нет существующих стандарт функции для 64-битных типов.
Однако в Linux, использующем библиотеку GNU C, есть bswap_x
набор функций, которые имеют 64-битный вариант.
Других решений пока нет …