C UINT16 Как все исправить?

Я новичок в программировании на C, и я тестирую код, в котором я получаю и обрабатываю UDP-пакет, отформатированный следующим образом:

UINT16 port1 UINT16 port2 

Соответствующие значения в этом тесте:

 6005 5555 

Если я печатаю весь пакетный буфер, я получаю что-то вроде этого:

u^W³^U>^D

Поэтому я подумал, что мне просто нужно сломать его и обработать как unsigned int из 16 байтов. Поэтому я пробовал что-то вроде этого:

 int l = 0; unsigned int *primaryPort = *(unsigned int) &buffer[l]; AddToLog(logInfo, "PrimaryPort: %u\n", primaryPort); l += sizeof(primaryPort); unsigned int *secondaryPort = *(unsigned int) &buffer[l]; AddToLog(logInfo, "SecondaryPort: %u\n", secondaryPort); l += sizeof(secondaryPort); 

Но я получаю неправильные цифры с 8 цифрами.

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

 int l = 0; unsigned char primaryPort[16]; snprintf(primaryPort, sizeof(primaryPort), "%u", &buffer[l]); AddToLog(logInfo, "PrimaryPort: %d\n", primaryPort); l += sizeof(primaryPort); unsigned char secondaryPort[16]; snprintf(secondaryPort, sizeof(secondaryPort), "%u", &buffer[l]); AddToLog(logInfo, "SecondaryPort: %d\n", secondaryPort); l += sizeof(secondaryPort); 

Что я делаю неправильно? Кроме того, почему я должен освобождать строковые переменные char, но мне не нужно освобождать переменные int?

Вы переходите к указателям AddToLog и snprintf к целым числам. Итак, вы видите адреса целых чисел, а не целые числа.

Вам нужно разыменовать свои указатели – например, перед primaryPort в ваших вызовах AddToLog в первый подход поставить звездочку (*).

Как предлагает @rileyberton, скорее всего, unsigned int составляет 4 байта в вашей системе, то есть u9932 типа C99. Для 16-разрядного целого используйте uint16_t . Они определены в stdint.h . Они традиционно называются «короткими целыми числами» или «полными целыми числами» и требуют квалификатора %hu в printf или подобных функциях, а не только %u (что означает unsigned int , размер которого зависит от целевой машины).

Кроме того, как предполагает @ igor-tandetnik, вам может потребоваться переключить порядок байтов целых чисел в вашем пакете, если, например, пакет использует формат сетевого порядка (big-endian), а ваша целевая машина использует формат little-endian.

unsigned int в вашей системе, скорее всего, 4 байта (uint32_t). Вы можете использовать unsigned int здесь, если вы замаскируете значения в правильной энтиансе или просто используете короткий.

 int l = 0; unsigned short *primaryPort = *(unsigned short) &buffer[l]; AddToLog(logInfo, "PrimaryPort: %u\n", primaryPort); l += sizeof(*primaryPort); unsigned short *secondaryPort = *(unsigned short) &buffer[l]; AddToLog(logInfo, "SecondaryPort: %u\n", secondaryPort); l += sizeof(*secondaryPort); 

Вы объявили primaryPort и secondaryPort указателями на unsigned short .

Но когда вы присваиваете им значения из раздела буфера, вы уже удалили указатель. Вам не нужны pointers-to-unsigned-short . Вам просто нужен unsigned short знак.

Измените его на:

 unsigned short primaryPort = *((unsigned short*) &buffer[l]); unsigned short secondaryPort = *((unsigned short *) &buffer[l]); 

Обратите внимание на удаление символа * в объявлениях переменных.

Если у вас все еще есть проблемы, вам нужно будет побайтовать buffer , ожидая ожидаемого значения. Вы можете ожидать, что 6005 будет отображаться как шестнадцатеричный 17 75 или 75 17 , в зависимости от консистенции вашей платформы.