C uint16整数或char格式化?

时间:2013-10-15 12:16:00

标签: c uint16

我是C编程的新手,我正在测试一些代码,我收到并处理格式化如下的UDP数据包:

UINT16 port1
UINT16 port2

此测试的相应值为:

6005
5555

如果我打印整个数据包缓冲区,我会得到这样的结果:

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

如何打破它并获得正确的价值?我已经尝试了uint16_tunsigned short甚至是htons函数,但是我没有工作,我只是得到错误的数字,我正在尝试这样的事情:

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

获得这些价值观的正确或最佳方式是什么?我认为这两个uint16值不是整数格式化的,我认为它只是这个字符uint16上的u^W³^U><9e>^D字符文本,所以也许我得错了数字,因为我处理的是整数。但我已经尝试了一切,但我无法获得正确的价值观。

1 个答案:

答案 0 :(得分:0)

当我看到你收到的缓冲区时,它确实以6005(小端)开始:

6005是0x1775,前两个字符是u(0x75)和Ctrl-W(0x17)。所以你应该通过以下方式得到int值:

 unsigned short primaryPort = (buffer[l] & 0xff) | ((buffer[l+1] & 0xff) << 8 );

和辅助端口相同。

修改

它的工作原因是:

buffer[l] & 0xff之类的表达式中,buffer[i]被隐式投放到int中(搜索“整数提升”以了解详情)。如果0xffbuffer,则必须使用char *屏蔽它:然后buffer[i]已签名的字符,因此,如果设置了最高位,它的值是负的(例如'\xff'是-1)。屏蔽它确保我们得到0到25​​5范围内的正值。最后但并非最不重要的是,移位运算符<< 8将字节值移位到计算出的int的下一个更高字节。最后,完整操作的结果被隐式地转换为unsigned short,这可以安全地完成,因为计算出的int小于或等于0xffff。