【问题标题】:Dotted decimal to binary in CC中的点分十进制到二进制
【发布时间】:2014-10-07 00:16:56
【问题描述】:

我有一个带有 IP 地址的 in_addr 结构,我正在尝试将其从点分十进制转换为二进制值。我真正需要做但无法工作的事情是

destn = inet_addr(inet_ntoa(addr));

其中addrin_addr_t 变量。我知道这违反了语法,但是当我更仔细地遵循语法时,我得到一个错误:

storage size of ‘addr’ isn’t known.

【问题讨论】:

  • 您是指文本“11000000101010000000000000000001”意义上的二进制值还是 32 位无符号整数意义上的二进制值?
  • 抱歉,应该指定 -- 在 32 位无符号整数的意义上。
  • 什么是dotted decimal?举个例子,把你的问题编辑成可读的形式,不要输入随机信息,它可能会关闭
  • @chouaib Dotted decimal 是表示 IP 地址的标准形式。仅仅因为你不知道某事并不意味着它的“随机信息”。在告诉 OP 修改他的问题之前做你的研究。
  • @s_frank “点分十进制”只是以文本方式表示 IPv4 地址的一种方式。另一个是 32 位十六进制值,一串 1 和 0 是另一个。如果您有一个in_addr 结构,那么您已经在内存中获得了“二进制”形式的值。你接下来实际上想用这个值完成什么?打印出来?我认为您需要显示更多代码。这个问题现在无法回答。

标签: c linux network-programming


【解决方案1】:

如果您在 struct in_addr 变量中已有 IPv4 地址,则无需执行任何操作:

/* Internet address. */
struct in_addr {
    uint32_t       s_addr;     /* address in network byte order */
};

ip(7)。只需访问 s_addr 字段,您的 IPv4 地址就会是一个简单的 32 位整数。

示例程序:

#include <stdio.h>
#include <inttypes.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    struct in_addr addr = {};
    const char *ip_str;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s ip-addr\n", argv[0]);
        return 1;
    }
    ip_str = argv[1];

    if (!inet_aton(ip_str, &addr)) {
        fprintf(stderr, "Invalid IP address: %s\n", ip_str);
        return 1;
    }

    printf("Address: 0x%08"PRIX32"\n", addr.s_addr);
    // Just access the s_addr field --------^

    return 0;
}

示例用法:

$ gcc -Wall -Werror in.c 
$ ./a.out 192.168.7.4
Address: 0x0407A8C0
           ^ ^ ^ ^
           | | | \---- 192
           | | \------ 168
           | \-------- 7
           \---------- 4

【讨论】:

  • 非常感谢@Jonathon Reinhart 和@Steve 的帮助!
【解决方案2】:

为了将来的兼容性,您应该同时处理 IP 4 和 6。否则,您可能会提到 inet_ntoa 而不是 inet_ntop。 (我的手机使用 IP 6,所以如果我在手机上进行 IP 编程,我需要允许它。)那么,如何?下面是我的开始:

char *address_string;

(填写address_string的值。)

struct in_addr addr4;
int success4 = inet_pton(AF_INET, address_string, addr4);
struct in6_addr addr6;
int success6 = inet_pton(AF_INET6, address_string, addr6);

当然,您需要添加错误处理。

如果您尝试获取二进制 IP 号码的文本表示,这应该可以完成工作:

struct in_addr addr4;
struct in6_addr addr6;
bool address_is_ip6;

(填写 IP 4 或 6 地址的值,并注意您使用的是哪一个。)

socklen_t ip6_maximum_length = 40;
char address_string[ip6_maximum_length];
char *result = inet_ntop(address_is_ip6 ? AF_INET6 : AF_INET, address_is_ip6 ? &addr6 : &addr4, address_string, ip6_maximum_length);

同样,您需要进行错误处理。

【讨论】:

  • 虽然这是一个很好的一般性建议,但它并不能回答 OP 的问题(可能是因为我们不知道他实际需要什么)。他表示他已经有一个带有 IP 地址的 in_addr 结构,因此在这里解析字符串似乎不合适。
  • 最初的问题有点不清楚,一方面提到起点是in_addr 结构,其目的是“从点分十进制转换为二进制值”。基于二进制值“在 32 位无符号整数的意义上”对我的澄清问题的回复,我假设目的是将文本转换为 in_addr(或 in6_addr)结构,并提供代码那。 为什么投反对票? 无论如何,现在我已经提供了两种方式转换的代码。
猜你喜欢
  • 2015-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-23
  • 2014-04-19
  • 2019-04-09
  • 2017-08-22
相关资源
最近更新 更多