【问题标题】:Error from socket() call来自 socket() 调用的错误
【发布时间】:2012-03-08 14:54:37
【问题描述】:

我想为我的程序添加 IPv6 支持,但遇到了奇怪的错误。我想打开接受连接的套接字。这是我的场景:

首先我使用 getaddrinfo() 来查找套接字配置:

struct addrinfo hint, *info = NULL;

memset((void *)&hint, 0, sizeof(hint));
hint.ai_family = AF_INET6;
hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
hint.ai_socktype = SOCK_STREAM;

if ((error = getaddrinfo(NULL, "1234", &hint, &info))) {
    /* some error handling */
}

我在info 中生成非NULL 结果。然后我想创建套接字:

socket(info->ai_family, info->ai_socktype, info->ai_protocol)

我在这里得到-1

strerror(errno)

返回Address family not supported by protocol

我认为getaddrinfo() 只返回可以绑定的地址,我希望它在这种情况下返回 NULL。我错过了什么?

我想补充一点,我的 eth0 现在没有 IPv6 地址。我正在使用 uClibc 0.9.32

【问题讨论】:

  • 你得到你想要的......否则删除hint.ai_family = AF_INET6;

标签: c linux sockets uclibc


【解决方案1】:

您需要将AI_ADDRCONFIG 添加到ai_flags 以确保它不会返回内核不支持的地址族。我现在几乎总是添加那个标志。

如果您想支持没有 IPv6 的内核,您必须避免将 ai_family 设置为 AF_INET6。相反,您必须监听所有返回的地址,并确保在 AF_INET6 上设置 IPV6_V6ONLY。不幸的是,不能保证首先返回 AF_INET6 地址。

【讨论】:

  • 今天这救了我的培根!谢谢!
  • @gubblebozer 很高兴为您提供帮助。我想指出,到目前为止,我总是首先尝试将 AF_INET6 传递给 getaddrinfo。如果该或以下套接字调用失败,我将回退到AF_INET。它的代码更多,但拥有一个监听套接字会使其他地方的事情变得更容易(如果你这样做,请确保关闭关闭 IPV6_V6ONLY)。
【解决方案2】:

getaddrinfo 返回struct addrinfo 对象的链表,您可以使用ai_next 成员对其进行遍历。您应该依次尝试每个返回的 addrinfo 对象,直到获得连接(或点击 NULL/end of list)。

【讨论】:

    猜你喜欢
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    相关资源
    最近更新 更多