2

getaddrinfo()在 Linux 中,我可以使用对本地套接字的调用getaddrinfo(NULL,port,&hints,&servinfo)来创建如下列表:

   IPv4: 0.0.0.0
 | socktype: 1 |protocol: 6    IPv4: 0.0.0.0
 | socktype: 2 |protocol: 17    IPv4: 0.0.0.0
 | socktype: 3 |protocol: 0    IPv6: ::
 | socktype: 1 |protocol: 6    IPv6: ::
 | socktype: 2 |protocol: 17    IPv6: ::
 | socktype: 3 |protocol: 0

而在 Windows 中,任何与本地机器"NULL", "localhost",相关的调用"127.0.0.1"(实际上,任何不是 URL 的)似乎都失败了。

getaddrinfo()linux和windows在使用上的预期区别是什么?

另外-我知道这种问题会使问题变得复杂-但是第一个程序的输出到底告诉了我什么?这些是内核可以为该端口提供的唯一组合吗?

是的,这个问题是从相当著名的“Beej 网络编程指南”演变而来的。

导致此的代码如下:

      struct addrinfo hints,*ai,*p;

    memset(&hints,0,sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = AI_PASSIVE;
    int error;

   memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;

if ((error = getaddrinfo("www.example.com", "http", &hints, &ai)) != 0) {
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error));
    exit(1);
} else cout <<"Success with a URL\n";


if (error=(getaddrinfo("208.117.45.202",&port,&hints,&ai))){
       cout<<"Cannot resolve any usable ports! : "<<gai_strerror(error)<< " : "<<error;
       if (ai == NULL) return -5;
}

谢谢!

4

2 回答 2

2

这些神奇的东西叫做手册页。例如,man 3 getaddrinfo明确表示

如果在 hints.ai_flags 中指定了 AI_PASSIVE 标志,并且 node 为 NULL,则返回的套接字地址将适合用于 连接bind()的套接字accept()。返回的套接字地址将包含“通配符地址”(INADDR_ANY 用于 IPv4 地址,IN6ADDR_ANY_INIT 用于 IPv6 地址)。通配符地址由打算接受任何主机网络地址上的连接的应用程序(通常是服务器)使用。如果 node 不为 NULL,则忽略 AI_PASSIVE 标志。

getaddrinfo()函数的目的很简单:它尽最大努力将用户指定的字符串转换为应用程序可以用来创建套接字的数字数据,一个监听传入连接或一个用于连接。

getaddrinfo()POSIX.1-2001(和RFC 2553)中指定,并且微软以从不遵循它可以扩展或破坏的标准而闻名,所以当然它在 Windows 中是一个完全不同的功能。相关的MSDN 页面称它“提供了从 ANSI 主机名到地址的独立于协议的转换”。

您的程序的输出,因为node(第一个参数)是NULL,并且您AI_PASSIVE在标志中拥有,是您的程序可以(尝试)绑定到的通配符地址列表,以侦听port您指定的传入连接。

于 2013-07-03T02:41:49.830 回答
0

编码一致性发生了什么?

memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
int error;

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;

hints你先用sizeof(hints);归零 然后你设置一些值;sizeof hints然后用(不一致)再次将其归零;然后您再次设置一些值并错过其他值(尤其是AI_PASSIVE标志)。如果你保持一致,编程通常是最简单的。避免做(或多或少)同样的事情两次也是明智的。选择一个或另一个序列,但不要同时包含两者。

这是否真的是你问题的根源是一个单独的问题。Nominal Animal回答涵盖了许多相关领域,尽管我尚未验证 Microsoft 特定的细节。

于 2013-07-03T06:33:45.093 回答