C UINT16 How to get it right?

2020-03-31 08:08发布

问题:

I'm new on C programming and I'm testing some code where I receive and process an UDP packet formatted as follow:

UINT16 port1
UINT16 port2

The corresponding values on this test are:

6005
5555

If I print the whole packet buffer I get something like this:

u^W³^U><9e>^D

So I thought that I would just have to break it and process as an unsigned int of 16 bytes. So I've tried something like this:

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

But I get wrong numbers with 8 digits.

I even tried another approach like follow, but also get the wrong number as well.

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

What I'm doing wrong? Also, why I have to free on a char string variables, but I don't need to free on int variables?

回答1:

You are passing to AddToLog and snprintf pointers to the integers. So what you're seeing are the addresses of the integers, not the integers themselves.

You need to dereference your pointers -- for example, put an asterisk (*) in front of primaryPort in your calls to AddToLog in your first approach.

As @rileyberton suggests, most likely unsigned int is 4 bytes on your system, which is the C99 type uint32_t. For a 16-bit integer, use uint16_t. These are defined in stdint.h. These are traditionally called "short integers" or "half integers" and require the %hu qualifier in printf or similar functions, rather than just %u (which stands for unsigned int, whose size depends on the target machine.)

Also, as @igor-tandetnik suggests, you may need to switch the byte order of the integers in your packet, if for example the packet is using network order (big-endian) format and your target machine is using little-endian format.



回答2:

unsigned int on your system is likely 4 bytes (uint32_t). You can use unsigned int here if you mask out the values in the correct endianess, or simply use a short.

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


回答3:

You declared primaryPort and secondaryPort to be pointers to unsigned short.

But when you assign them values from a section of buffer, you already de-referenced the pointer. You don't need pointers-to-unsigned-short. You just need an unsigned short.

Change it to:

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

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

Note the removal of a * in the variable declarations.

If you're still having problems, you'll need to examine buffer byte-by-byte, looking for the value you expect. You can expect that 6005 will show up as either hex 17 75 or 75 17, depending on your platform's endianness.



标签: c int uint16