getaddrinfo() - Linux VS Windows

时间:2013-07-02 08:02:07

标签: c linux windows network-programming

在Linux中,我可以使用getaddrinfo()调用本地套接字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"(实际上,任何不是网址)相关的任何调用似乎都失败了。

linux和windows之间getaddrinfo()的使用有何不同?

另外 - 我知道这种问题是两个问题 - 但是第一个程序的输出究竟告诉我什么?这些是内核可以为该端口提供的唯一组合吗?

是的,这个问题是从着名的“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;
}

谢谢!

2 个答案:

答案 0 :(得分:2)

这些神奇的东西叫man pages。例如,man 3 getaddrinfo明确表示

  

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

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

POSIX.1-2001(和RFC 2553)中指定了

getaddrinfo(),并且Microsoft因其永远不会遵循它可能扩展或变态的标准而闻名,所以当然它在Windows中是完全不同的功能。相关MSDN page表示“提供从ANSI主机名到地址的协议无关转换。”

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

答案 1 :(得分: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标志)。如果您保持一致,编程通常是最简单的。同样避免做(或多或少)同样的事情两次也是明智的。选择一个或另一个序列,但不要同时包含这两个序列。

这是否真的是您的问题的根源是一个单独的问题。 answer Nominal Animal涵盖了很多相关的基础,但我没有验证微软特定的细节。