C Linux系统调用:getaddrinfo return-2

C Linux系统调用:getaddrinfo return-2,c,linux,system-calls,C,Linux,System Calls,我正在使用系统调用getaddrinfo,它返回-2。我试图知道这是什么错误,并得到这是“名称或服务未知”。 名字-这是我的主机名,我相信它是已知的。但该服务是一个在不同运行时更改的编号。我怎么知道我带了正确的参数 我的代码: int GetSockPeerIPs(int sock, AddressList &addresses, int &error, int family, bool zeroport) { struct socka

我正在使用系统调用getaddrinfo,它返回-2。我试图知道这是什么错误,并得到这是“名称或服务未知”。 名字-这是我的主机名,我相信它是已知的。但该服务是一个在不同运行时更改的编号。我怎么知道我带了正确的参数

我的代码:

int GetSockPeerIPs(int sock, AddressList &addresses, int &error,
                  int family, bool zeroport)
{
    struct sockaddr_storage ss;
    socklen_t salen = sizeof(ss);
    struct sockaddr *sa;
    struct addrinfo hints, *paddr, *paddrp;

    sa = (struct sockaddr *)&ss;

    if (getpeername(sock, sa, &salen) != 0) {
        error = errno;
        return -1;
    }

    char hbuf[NI_MAXHOST];
    char pbuf[NI_MAXSERV];
    if (0 != (error = getnameinfo(sa, salen,
                      hbuf, sizeof(hbuf),
                      pbuf, sizeof(pbuf),
                      0))) {
        return -1;
    }

    memset(&hints, 0, sizeof(hints));
    if (ATNetworkTool::AF_XINETX == family) {
        hints.ai_family = PF_UNSPEC;
    } else {
        hints.ai_family = family;
    }
    hints.ai_socktype = SOCK_STREAM;
    if (0 != (error = getaddrinfo(hbuf, pbuf, &hints, &paddrp))) {
        return -1;
    }
    addresses.clear();
    for (paddr = paddrp; paddr; paddr = paddr->ai_next) {
        if (ATNetworkTool::AF_XINETX == family) {
            if (!ATAddress::saIsInet(paddr->ai_addr)) {
                continue;
            }
        }
        if (zeroport) {
            addresses.insert(ATAddress(paddr->ai_addr, 0));
        } else {
            addresses.insert(paddr->ai_addr);
        }
    }
    freeaddrinfo(paddrp);
    return 0;
}
谢谢!
gln

您有一个错误代码。你有没有想过要弄清楚这是什么意思?这次我是为你做的。但我是这么做的,这样你下次就可以自己查了

查看手册页,我发现它可能会再次返回许多错误代码,例如EAI_。数值将在某个地方的头文件中定义,所以我这样做了

cd /usr/include
find . -name "*.h" -exec grep -l EAI_AGAIN {} \;
这标识为netdb.h。我在vi中打开了它,它是这样说的:

# define EAI_BADFLAGS     -1    /* Invalid value for `ai_flags' field.  */
# define EAI_NONAME       -2    /* NAME or SERVICE is unknown.  */
# define EAI_AGAIN        -3    /* Temporary failure in name resolution.  */
# define EAI_FAIL         -4    /* Non-recoverable failure in name res.  */
# define EAI_FAMILY       -6    /* `ai_family' not supported.  */
# define EAI_SOCKTYPE     -7    /* `ai_socktype' not supported.  */
# define EAI_SERVICE      -8    /* SERVICE not supported for `ai_socktype'.  */
# define EAI_MEMORY       -10   /* Memory allocation failure.  */
# define EAI_SYSTEM       -11   /* System error returned in `errno'.  */
# define EAI_OVERFLOW     -12   /* Argument buffer overflow.  */

因此,基本上,您传递的名称或服务对getaddrinfo是未知的。如果我是你的话,我会检查前两个参数是否合理。

getaddrinfo
对数据的格式很挑剔,在解析配置文件时,请确保主机名参数中没有额外的空格(通常是尾随空格),否则会出现此错误,在本例中,错误是正确的,只是信息量不大。

注意,如果getaddrinfo()和friends失败,您可以调用返回代码以获取文本错误消息。e、 g.
printf(“getaddrinfo()失败:%s\n”,gai_strerror(错误))
在您的案例ftr中,getaddrinfo不会是一个系统调用。仅供参考
grep-r--include=\*.h EAI\u再次/usr/include
比使用
find
生成
grep
,因为它只生成一个
grep
进程,而不是每个头文件生成一个进程。@Adam Rosenfield:Correct,但谁在乎它能完成任务呢?你有没有用grep处理过一个包含上万个文件的源代码树?一个grep实例在几秒钟内运行。为每个文件分叉一个新的进程需要更长的时间,大约是分钟或更多。@Adam:是的。自20世纪80年代中期以来,我在任何一台机器上工作过,grep都没有在一个典型的C头大小的文件上花费“几秒钟”的时间。而且,在当时,
-r
标志和
-include
标志并不存在。我没有说你解决这个问题的方法有什么问题——对于一个大小为
/usr/include
的文件树,它不会有太大的区别——但是对于更大的问题,它会有区别。在80年代中期,您可能没有包含成千上万个文件的代码库。当然,如果你使用的是一个过时的grep,它没有
-r
-include
,那么就继续使用
查找
,但是现在大多数grep都有这些标志。