C 从结构addrinfo中提取十六进制IP

C 从结构addrinfo中提取十六进制IP,c,tcp,ip,C,Tcp,Ip,我已经用数据填充了我的结构struct addrinfo**res: err = getaddrinfo(argv[1], NULL, &hints, &res); 如果我想打印IP地址,我可以使用 addr.s_addr = ((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr; printf("ip address : %s\n", inet_ntoa(addr)); 例如,这将打印10.111.1.1

我已经用数据填充了我的结构
struct addrinfo**res

err = getaddrinfo(argv[1], NULL, &hints, &res);
如果我想打印IP地址,我可以使用

addr.s_addr = ((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr;
printf("ip address : %s\n", inet_ntoa(addr));
例如,这将打印
10.111.1.11
。但我需要十六进制格式的IP,即
0A6F010B
。 我提出了以下内容,它将以十六进制格式打印IP:

for (i=0; i<32; i=i+8)
    printf("%02X",(addr.s_addr>>i) % 256) ;
我得到以下输出(对应于
10.111.1.11
):

但格式并不像上一个示例中那样简单。例如,对于
172.25.0.31
我得到以下输出:

00-842503100000000
因此,我的问题是:
如何将这种胡言乱语转换为十六进制IP地址?

看一看
inet\u ntoa
的实现:

您只需以所需格式交换即可更改其实现以满足您的需要,即十六进制:

snprintf(b, sizeof(b), "%02X%02X%02X%02X", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));

请注意,他们的解决方案不是线程安全的,因为它对输出使用函数静态缓冲区。要使其线程安全,请将函数更改为获取输出缓冲区,并要求缓冲区至少包含九个字符(八个字符用于十六进制输出,另一个字符用于空终止符)。

请查看
inet\u ntoa
的实现:

您只需以所需格式交换即可更改其实现以满足您的需要,即十六进制:

snprintf(b, sizeof(b), "%02X%02X%02X%02X", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));

请注意,他们的解决方案不是线程安全的,因为它使用函数静态缓冲区作为输出。要使其线程安全,请将函数更改为使用输出缓冲区,并要求缓冲区至少包含九个字符(八个用于十六进制输出,另一个用于空终止符。

请看一下inet\u ntoa的实现:

您只需以所需格式交换即可更改其实现以满足您的需要,即十六进制:

snprintf(b, sizeof(b), "%02X%02X%02X%02X", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));

请注意,他们的解决方案不是线程安全的,因为它使用函数静态缓冲区作为输出。要使其线程安全,请将函数更改为使用输出缓冲区,并要求缓冲区至少包含九个字符(八个用于十六进制输出,另一个用于空终止符。

请看一下inet\u ntoa的实现:

您只需以所需格式交换即可更改其实现以满足您的需要,即十六进制:

snprintf(b, sizeof(b), "%02X%02X%02X%02X", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
请注意,他们的解决方案不是线程安全的,因为它使用函数静态缓冲区作为输出。要使其线程安全,请将函数更改为使用输出缓冲区,并要求缓冲区至少包含九个字符(八个用于十六进制输出,另一个用于空终止符。

根据and,您需要进行一些动态类型更改。使用正确的类型,它可能看起来像这样:

struct addrinfo * res;
err = getaddrinfo(argv[1], NULL, &hints, &res);

// check that the operation succeeded
assert(err == 0);

// check that the dynamic type is AF_INET
assert(res->ai_addr->sa_family == AF_INET);

// downcast
struct sockaddr_in * p = (struct sockaddr_in *)(res->ai_addr);

// done
printf("Address: %08X (%s)\n", p->sin_addr.s_addr, inet_ntoa(p->sin_addr));

执行正确动态类型选择的更完整示例可能如下所示:

char str[128];

switch (res->ai_addr->sa_family)
{
  case AF_INET:
  {
      struct sockaddr_in * p = (struct sockaddr_in *)(res->ai_addr);
      if (inet_ntop(p->sin_family, &p->sin_addr, str, sizeof str) == NULL)
          fprintf(stderr, "Error in inet_ntop: %s\n", strerror(errno));
      else
          printf("Address: %08X (%s)\n", p->sin_addr.s_addr, str);
      break;
  }
  case AF_INET6:
  {
      struct sockaddr_in6 * p = (struct sockaddr_in6 *)(res->ai_addr);
      if (inet_ntop(p->sin6_family, &p->sin6_addr, str, sizeof str) == NULL)
          fprintf(stderr, "Error in inet_ntop: %s\n", strerror(errno));
      else
          printf("Address: %s\n", str);
      break;
  }
  default:
  {
      fprintf(stderr, "Unrecogized address family, skipping.\n");
  }
}
根据和,您需要执行一些动态类型更改。使用正确的类型,它可能看起来像这样:

struct addrinfo * res;
err = getaddrinfo(argv[1], NULL, &hints, &res);

// check that the operation succeeded
assert(err == 0);

// check that the dynamic type is AF_INET
assert(res->ai_addr->sa_family == AF_INET);

// downcast
struct sockaddr_in * p = (struct sockaddr_in *)(res->ai_addr);

// done
printf("Address: %08X (%s)\n", p->sin_addr.s_addr, inet_ntoa(p->sin_addr));

执行正确动态类型选择的更完整示例可能如下所示:

char str[128];

switch (res->ai_addr->sa_family)
{
  case AF_INET:
  {
      struct sockaddr_in * p = (struct sockaddr_in *)(res->ai_addr);
      if (inet_ntop(p->sin_family, &p->sin_addr, str, sizeof str) == NULL)
          fprintf(stderr, "Error in inet_ntop: %s\n", strerror(errno));
      else
          printf("Address: %08X (%s)\n", p->sin_addr.s_addr, str);
      break;
  }
  case AF_INET6:
  {
      struct sockaddr_in6 * p = (struct sockaddr_in6 *)(res->ai_addr);
      if (inet_ntop(p->sin6_family, &p->sin6_addr, str, sizeof str) == NULL)
          fprintf(stderr, "Error in inet_ntop: %s\n", strerror(errno));
      else
          printf("Address: %s\n", str);
      break;
  }
  default:
  {
      fprintf(stderr, "Unrecogized address family, skipping.\n");
  }
}
根据和,您需要执行一些动态类型更改。使用正确的类型,它可能看起来像这样:

struct addrinfo * res;
err = getaddrinfo(argv[1], NULL, &hints, &res);

// check that the operation succeeded
assert(err == 0);

// check that the dynamic type is AF_INET
assert(res->ai_addr->sa_family == AF_INET);

// downcast
struct sockaddr_in * p = (struct sockaddr_in *)(res->ai_addr);

// done
printf("Address: %08X (%s)\n", p->sin_addr.s_addr, inet_ntoa(p->sin_addr));

执行正确动态类型选择的更完整示例可能如下所示:

char str[128];

switch (res->ai_addr->sa_family)
{
  case AF_INET:
  {
      struct sockaddr_in * p = (struct sockaddr_in *)(res->ai_addr);
      if (inet_ntop(p->sin_family, &p->sin_addr, str, sizeof str) == NULL)
          fprintf(stderr, "Error in inet_ntop: %s\n", strerror(errno));
      else
          printf("Address: %08X (%s)\n", p->sin_addr.s_addr, str);
      break;
  }
  case AF_INET6:
  {
      struct sockaddr_in6 * p = (struct sockaddr_in6 *)(res->ai_addr);
      if (inet_ntop(p->sin6_family, &p->sin6_addr, str, sizeof str) == NULL)
          fprintf(stderr, "Error in inet_ntop: %s\n", strerror(errno));
      else
          printf("Address: %s\n", str);
      break;
  }
  default:
  {
      fprintf(stderr, "Unrecogized address family, skipping.\n");
  }
}
根据和,您需要执行一些动态类型更改。使用正确的类型,它可能看起来像这样:

struct addrinfo * res;
err = getaddrinfo(argv[1], NULL, &hints, &res);

// check that the operation succeeded
assert(err == 0);

// check that the dynamic type is AF_INET
assert(res->ai_addr->sa_family == AF_INET);

// downcast
struct sockaddr_in * p = (struct sockaddr_in *)(res->ai_addr);

// done
printf("Address: %08X (%s)\n", p->sin_addr.s_addr, inet_ntoa(p->sin_addr));

执行正确动态类型选择的更完整示例可能如下所示:

char str[128];

switch (res->ai_addr->sa_family)
{
  case AF_INET:
  {
      struct sockaddr_in * p = (struct sockaddr_in *)(res->ai_addr);
      if (inet_ntop(p->sin_family, &p->sin_addr, str, sizeof str) == NULL)
          fprintf(stderr, "Error in inet_ntop: %s\n", strerror(errno));
      else
          printf("Address: %08X (%s)\n", p->sin_addr.s_addr, str);
      break;
  }
  case AF_INET6:
  {
      struct sockaddr_in6 * p = (struct sockaddr_in6 *)(res->ai_addr);
      if (inet_ntop(p->sin6_family, &p->sin6_addr, str, sizeof str) == NULL)
          fprintf(stderr, "Error in inet_ntop: %s\n", strerror(errno));
      else
          printf("Address: %s\n", str);
      break;
  }
  default:
  {
      fprintf(stderr, "Unrecogized address family, skipping.\n");
  }
}


如果你想要十六进制,为什么要使用十进制的
%d
。你也在星星中迷失了方向。你的
res
应该是
struct addrinfo*
。如果你想要十六进制,为什么要使用十进制的
%d
。你也在星星中迷失了方向。你的
res
应该是
struct addrinfo*
。如果你想要nt hex,你为什么要使用十进制的
%d
。你也在星星中迷失了方向。你的
res
应该是
struct addrinfo*
。如果你想要十六进制,为什么要使用十进制的
%d
。你也在星星中迷失了方向。你的
res
应该是
struct addrinfo*
。但这会发生t十六进制IP反向,即
0B016F0A
而不是正确的
0A6F010B
@MartinVegter:这不是反向。相反的是您的期望:-)与其说是我的期望,不如说是我的
tftp
服务器的期望。@MartinVegter:我添加了一个方便的函数调用来帮助您的服务器。这很好,但我仍然需要“反转”十六进制IP。但这将以相反的方式打印十六进制IP,即
0B016F0A
而不是正确的
0A6F010B
@MartinVegter:这不是相反的。相反的是您的期望:-)与其说是我的期望,不如说是我的
tftp
服务器的期望。@MartinVegter:我添加了一个方便的函数调用来帮助您的服务器。这很好,但我仍然需要“反转”十六进制IP。但这将以相反的方式打印十六进制IP,即
0B016F0A
而不是正确的
0A6F010B
@MartinVegter:这不是相反的。相反的是您的期望:-)与其说是我的期望,不如说是我的
tftp
服务器的期望。@MartinVegter:我添加了一个方便的函数调用来帮助您的服务器。这很好,但我仍然需要“反转”十六进制IP。但这将以相反的方式打印十六进制IP,即
0B016F0A
而不是正确的
0A6F010B
@MartinVegter:这不是相反的。相反的是您的期望:-)与其说是我的期望,不如说是我的
tftp
服务器的期望。@MartinVegter:我添加了一个方便的函数调用来帮助您的服务器。这很好,但我仍然需要“反转”十六进制IP。