【问题标题】:How to use getaddrinfo()?如何使用 getaddrinfo()?
【发布时间】:2013-03-28 23:29:27
【问题描述】:

我正在尝试制作一个简单的程序,它接收像 www.google.com 这样的字符串并返回 IP 地址...

到目前为止我所拥有的:

char* hostname = new char[www.size()+1];
std::copy(www.begin(), www.end(), hostname);
hostname[www.size()] = '\0';

struct addrinfo new_addr, *res;

getaddrinfo(www.c_str(), SERVICE.c_str(), &new_addr, &res);



cout << new_addr.ai_addr;

第四个参数中的第三个应该做什么? getaddrinfo 函数是修改 new_addr 结构还是什么?我不太了解 msdn 文档。解析主机名后,我想将套接字连接到它。

【问题讨论】:

    标签: winsock winsock2 getaddrinfo


    【解决方案1】:

    如果我让第三个参数无效怎么办?

    这是我到目前为止开发的代码。

        char* hostname = new char[www.size()+1];
    copy(www.begin(), www.end(), hostname);
    hostname[www.size()] = '\0';
    
    struct addrinfo *res;
    struct in_addr addr;
    
    getaddrinfo(hostname, NULL, 0, &res);
    
    addr.S_un = ((struct sockaddr_in *)(res->ai_addr))->sin_addr.S_un;
    
    server.sin_addr.s_addr = inet_addr(inet_ntoa(addr));
    server.sin_port = htons(portno);
    
    freeaddrinfo(res);
    delete []hostname;
    

    server.sin 在其他地方声明,我用它来填充我的套接字类的另一个方法中的套接字。

    【讨论】:

      【解决方案2】:

      MSDN 文档非常详细,并准确解释了各种参数的用途。第三个参数允许您指定将与查找结果一起使用的套接字类型。这将根据需要优化结果。第四个参数返回实际结果。该文档还包含有关如何使用该功能的完整示例。那么有什么例子不清楚文档所说的内容?

      试试这个:

      struct addrinfo hints = {0};
      hints.ai_flags = 0;
      hints.ai_family = AF_UNSPEC; // IPv4 and IPv6 allowed
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = IPPROTO_TCP;
      
      struct addrinfo *res = NULL;
      
      if (getaddrinfo(www.c_str(), SERVICE.c_str(), &hints, &res) == 0)
      {
          TCHAR szIPAddr[64];
          DWORD szIPAddrLen;
          SOCKET skt;
      
          struct addrinfo *addr = res;
          do
          {
              skt = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
              if (skt == INVALID_SOCKET)
                  cout << "Unable to create socket, error " << WSAGetLastError() << endl;
              else
              {
                  szIPAddrLen = 64;
                  WSAAddressToString(addr->ai_addr, addr->ai_addrlen, NULL, szIPAddr, &szIPAddrLen);
      
                  cout << "Connecting to " << szIPAddr << " ..." << endl;
      
                  if (connect(skt, addr->ai_addr, addr->ai_addrlen) == 0)
                  {
                      cout << "Connected!" << endl;
                      break;
                  }
      
                  cout << "Unable to connect, error " << WSAGetLastError() << endl;
                  closesocket(skt);
                  skt = INVALID_SOCKET;
              }
      
              addr = addr->ai_next;
          }
          while (addr);
      
          freeaddrinfo(res);
      
          if (skt != INVALID_SOCKET)
          {
              // use skt as needed...
              closesocket(skt);
          }
      }
      

      【讨论】:

      • hints.ai_flags = 0;提示.ai_family = AF_UNSPEC; // IPv4 和 IPv6 允许 hints.ai_socktype = SOCK_STREAM;提示.ai_protocol = IPPROTO_TCP;所以提示结构充当了 getaddrinfo 函数的指导工具?
      • 提示是什么让我感到困惑。它本应作为getaddr函数的引导工具,但实际上并没有被修改对吗?
      • @Kelvin:不,第三个参数的内容没有被修改。它只是告诉函数结果将使用哪种类型的套接字,如何执行名称解析等。告诉函数做什么的行为特性。最后一个参数是分配并返回查找的实际结果。为什么这么难理解?
      • 我明白了。对于 res,它只是一个指针,我读到它将指向一个新的 addrinfo 结构。从那里你可以使用 res 来获得结果。所以我假设该函数使一个 new 或 mallocs 一个 get addrinfo 与 res 指向它对吗?我要去看看这个函数的源代码,看看我是否能看到它是如何更好地工作的。谢谢你的帮助。如果你想看,我正在为我个人使用的套接字制作一个课程。我仍然需要更新它。 bitbucket.org/kelvinsilva/keyclient-project/src/…
      • 是的,该函数为其输出分配addrinfo 结构的链表。使用完后,您可以使用 freeaddrinfo() 释放该列表。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      • 2014-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多