【问题标题】:I don't know how to use Beej's programm from his Guide我不知道如何从他的指南中使用 Beej 的程序
【发布时间】:2023-03-29 16:20:01
【问题描述】:

1我正在阅读 Beej 的编程网络指南。我阅读了他的代码并进行了重要更改以检查 ipv6,但它无法正常工作。无法获取ip地址。如何在 Linux 系统上使用它? https://i.imgur.com/USVzBw1.png

#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>


int main(int argc, char *argv[])
{
    struct addrinfo hints, *res, *p;
    int status;
    char ipstr[INET6_ADDRSTRLEN];

    if (argc != 2) {
        fprintf(stderr,"usage: showip hostname\n");
        return 1;
    }

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
    hints.ai_socktype = SOCK_STREAM;

    if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
        return 2;
    }

    printf("IP addresses for %s:\n\n", argv[1]);

    for(p = res;p != NULL; p = p->ai_next) {
        void *addr;
        char *ipver;

        // get the pointer to the address itself,
        // different fields in IPv4 and IPv6:
        if (p->ai_family == AF_INET) { // IPv4
            struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
            addr = &(ipv4->sin_addr);
            ipver = "IPv4";
        } else if (p->ai_family==AF_INET6) { // IPv6
            struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
            addr = &(ipv6->sin6_addr);
            ipver = "IPv6";
        }

        // convert the IP to a string and print it:
        inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
        printf("  %s: %s\n", ipver, ipstr);
    }

    freeaddrinfo(res); // free the linked list

    return 0;
}```

【问题讨论】:

  • 你确定这是 C++ 而不是 C?
  • 请不要粘贴代码运行的图片。无论如何,您的输出表明您有一个参数解析问题,而不是调用 getaddrinfo 的问题。
  • 在这种情况下有意义吗?

标签: c++ network-programming


【解决方案1】:

这看起来很可疑:

您检查以确保 argc 为 2 以验证您至少有一个参数。有道理

if (argc != 2) {

但后来:

if ((status = getaddrinfo(argv[2], NULL, &hints, &res)) != 0) {

您引用了argv[2],当argv 中的唯一有效指标是01 时,这是未定义的。

很确定您打算使用argv[1],如下所示:

if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {

另外,这是一个错误:

    // convert the IP to a string and print it:
    inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
    printf("  %s: %s\n", ipver, ipstr);

这些语句没有问题,但是当p-&gt;ai_family 既不是AF_INET 也不是AF_INET6 时,这些语句无论如何都会被执行。 addripver 未定义。因此,未定义的行为。是的,在 Linux 上,有很多不基于 IP 的地址类型。

欢迎您参考我的ResolveHostname function on Github

【讨论】:

  • 哦,谢谢。是的,我打错了,但在 Original 中我试着像你说的那样跑。结果是一样的。
  • 你的程序有多少个参数?您发布的代码显然是错误的。但是您发布的图片暗示您有一个 3 参数版本。
  • 我不确定 3 个参数。当我从 CLI 运行程序时,它是否将“./programName”视为参数?
  • 评论已更正。 "./programName" 始终是 argv[0]。命令行上程序的第一个真正参数是argv[1]。所以如果我调用./foo abc 那么argc 是2 而argv[1] 是"abc" 有意义吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多