根据您的编辑,您正在打印数据包
啊哈!这更有意义。当您创建一个指向 unsigned 值的 unsigned char 指针时,您有一个指向内存中值开头的指针,但该值的存储方式将取决于机器的字节序和 字节顺序 em> 数据包中的字节数。
简单地存储/打印出当前存储在内存中的字节并不困难,存储/打印每两个字节也不困难。每个都可以用类似的东西来完成:
/* all bytes stored in memory */
void prn_all (const unsigned char *p, size_t nbytes)
{
while (nbytes--)
printf ("0x%02x\n", p[nbytes]);
}
/* each 2-bytes stored in memory */
void prn_two (const unsigned char *p, size_t nbytes)
{
while (nbytes--) {
printf ("%02x", p[nbytes]);
if (nbytes % 2 == 0)
putchar ('\n');
}
}
...
unsigned u = 0xdeadbeef;
unsigned char *p = (unsigned char *)&u;
prn_all (p, sizeof u);
putchar ('\n');
prn_two (p, sizeof u);
会导致:
$ /bin/prn_uchar_byte
0xde
0xad
0xbe
0xef
dead
beef
现在要注意了。既然你提到了"packet",根据数据包是network-byte-order还是host-byte-order,你可能需要一个转换(或者简单的位移) 以按您需要的顺序获取字节。 C 提供了在 network-byte-order 和 host-byte-order 之间转换的函数,反之亦然,man 3 byteorder htonl, htons, ntohl, ntohs。需要,因为网络字节顺序是大端,而普通 x86 和 x86_64 是小端。如果你的包是网络字节序并且你需要主机字节序,你可以简单地调用ntohs(网络到主机short)将每个两字节值转换为主机顺序,例如
/* each 2-bytes converted to host byte order from network byte order */
void prn_two_host_order (const unsigned char *p, size_t nbytes)
{
for (size_t i = 0; i < nbytes; i+=2) {
uint16_t hostorder = ntohs (*(uint16_t*)(p+i));
printf ("%04" PRIx16 "\n", hostorder);
}
}
...
prn_two_host_order (p, sizeof u);
结果:
efbe
adde
(注意:ntohs 的原型(以及所有字节顺序转换)使用 exact-width 类型 uint16_t 和 uint32_t ——打印宏在inttypes.h 中——它还自动包含stdint.h)
您将确定您在"packets" 中的顺序,以了解是否需要进行字节顺序转换。这将取决于您如何获取数据。
把它放在一个简短的例子中,你可以这样做:
#include <stdio.h>
#include <inttypes.h>
#include <arpa/inet.h>
/* all bytes stored in memory */
void prn_all (const unsigned char *p, size_t nbytes)
{
while (nbytes--)
printf ("0x%02x\n", p[nbytes]);
}
/* each 2-bytes stored in memory */
void prn_two (const unsigned char *p, size_t nbytes)
{
while (nbytes--) {
printf ("%02x", p[nbytes]);
if (nbytes % 2 == 0)
putchar ('\n');
}
}
/* each 2-bytes converted to host byte order from network byte order */
void prn_two_host_order (const unsigned char *p, size_t nbytes)
{
for (size_t i = 0; i < nbytes; i+=2) {
uint16_t hostorder = ntohs (*(uint16_t*)(p+i));
printf ("%04" PRIx16 "\n", hostorder);
}
}
int main (void) {
unsigned u = 0xdeadbeef;
unsigned char *p = (unsigned char *)&u;
prn_all (p, sizeof u);
putchar ('\n');
prn_two (p, sizeof u);
putchar ('\n');
prn_two_host_order (p, sizeof u);
}
(注意:一些系统使用标题netinet/in.h而不是arpa/inet.h进行手册页中列出的字节顺序转换)
使用/输出的完整示例
$ /bin/prn_uchar_byte
0xde
0xad
0xbe
0xef
dead
beef
efbe
adde
您可以存储值而不是打印 - 但这留给您。看看事情,如果你有问题,请告诉我。