В соответствии с вашими правками вы печатаете пакеты
Ах, ха!Это имеет больше смысла.Когда вы создаете указатель unsigned char
на значение unsigned
, у вас есть указатель на начало значения в памяти, но то, как оно будет сохранено, будет зависеть от порядкового номера машины и порядка байтов 1008* байтов в пакете.
Простое сохранение / распечатка байтов, поскольку они в данный момент хранятся в памяти, не представляет трудностей, равно как и сохранение / печать каждого двухбайтовых.Каждое из них может быть выполнено с помощью чего-то похожего на:
/* 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"
, в зависимости от того, находится ли пакет в сетевой-байтовый порядок или хост-байтовый порядок , вам может потребоваться преобразование (или простые битовые сдвиги) вполучить байты в нужном вам порядке.C предоставляет функции для преобразования между сетевой-байтовый порядок и хост-байтовый порядок и наоборот с man 3 byteorder htonl, htons, ntohl, ntohs
.Необходим, потому что порядок байтов в сети - Big Endian, в то время как нормальные x86 и x86_64 - Little Endian.Если ваши пакеты имеют сетевой порядок байтов и вам нужен порядок байтов хоста, вы можете просто позвонить 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
(и всех преобразований метеорологов) используют точную ширину типы 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);
}
( note: некоторые системыиспользуйте заголовок netinet/in.h
вместо arpa/inet.h
для преобразования метеорологов, как указано на странице руководства)
Полный пример использования / Вывод
$ /bin/prn_uchar_byte
0xde
0xad
0xbe
0xef
dead
beef
efbe
adde
Вы можетехранить значения вместо печати - но это вам остается.Посмотрите вещи и дайте мне знать, если у вас есть вопросы.