7

我在inet_aton转换网络地址时遇到问题。下面的代码可以很好地转换地址10.0.0.1

char *x1;
struct sockaddr_in si_other;
inet_aton("10.0.0.1", &si_other.sin_addr);
printf("si_other.sin_addr =%lu\n",si_other.sin_addr);
x1 = inet_ntoa(si_other.sin_addr);
printf("x1=%s\n",x1);

它输出:

si_other.sin_addr =16777226
x1=10.0.0.01

到目前为止没有问题。010.000.000.001但是,该函数在传递时工作起来很奇怪

char *x2;
struct sockaddr_in si_other2;
inet_aton("010.000.000.001", &si_other2.sin_addr);
printf("si_other2.sin_addr =%lu\n",si_other2.sin_addr);
x2 = inet_ntoa(si_other2.sin_addr);
printf("x2=%s\n",x2);

输出:

si_other.sin_addr2 =16777224
x2=8.0.0.01

该函数在192.168.0.1192.168.000.001被传递时工作正常。

谁能解释我是什么问题以及如何解决问题?(注意:我需要010.000.000.001在我的代码中传递 IP 地址)

4

1 回答 1

12

前导 0 被解释为表示数字是八进制的。010(八月)== 8(十二月)。您需要修改输入以inet_aton避免这种情况,或者以不同的方式自行转换。

const char *str = "010.000.000.001";
inet_aton(str[0] == '0' ? str+1:str, &si_other.sin_addr);

是最简单的解决方案,但最好先修复任何(snprintf?)产生字符串以避免混淆。

(就目前而言,该解决方案仍不适用于许多边缘情况,包括“001.0.0.1”、“0xF.0.0.1”、“1”和更多有效的 IPv4 地址)。

您可以使用 简单地“规范化”您的输入sscanf,即使您一开始就无法控制它的生成方式(尽管在我看来,这确实应该是一个错误):

#include <stdio.h>
#include <stdlib.h>

int main() {
  const char *str="010.020.030.040";
  int parts[4];
  sscanf(str, "%d.%d.%d.%d", parts+0, parts+1, parts+2, parts+3);
  char *out = NULL;
  asprintf(&out, "%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]);
  printf("%s\n", out);
  free(out);
  return 0;
}
于 2013-01-06T22:35:07.227 回答