gethostbyaddr返回0

时间:2012-03-22 15:13:00

标签: c++

我有一个包含IP地址的变量。我试图通过nslookup而不是返回的DNS名称,我得到0.我在Linux环境中。目标IP来自向量(字符串dest_ip = vector [2])。

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>

using namespace std;

void split(const std::string& str, std::vector<std::string>& v) {
    std::stringstream ss(str);
    ss >> std::noskipws;
    std::string field;
    char ws_delim;
    while(1) {
        if( ss >> field )
            v.push_back(field);
        else if (ss.eof())
            break;
        else
            v.push_back(std::string());
        ss.clear();
        ss >> ws_delim;
    }
}

int main()
{

  string input_line;

  while(cin){

  getline(cin, input_line);

   for(int i=0; input_line[i]; i++)
                      if(input_line[i] == ':') input_line[i] = ' ';
                     for(int i=0; input_line[i]; i++)
                      if(input_line[i] == '/') input_line[i] = ' ';

  std::vector<std::string> v;
  split(input_line, v);

  string dest_ip = v[4];

  struct hostent *he;
  int i,len,type;
  len = dest_ip.length();
  type=AF_INET;

  he = gethostbyaddr(dest_ip.c_str(),len,type);

  cout<<"Hostname: "<<he<<"\n";

  return 0;
}

同样,我没有收到主机名,而是获得0。

3 个答案:

答案 0 :(得分:4)

您无法将 c-style-string (即以null结尾)直接传递给gethostbyaddr

您需要创建一个struct in_addr并将指向已创建结构的指针作为第一个参数传递给gethostbyaddr。要从struct in_addr使用inet_aton生成char const*

以下示例摘自 man gethostbyaddr


<强>实施例

  • 打印出与特定IP地址关联的主机名:

    const char *ipstr = "127.0.0.1";
    struct in_addr ip;
    struct hostent *hp;
    
    if (!inet_aton(ipstr, &ip))
            errx(1, "can't parse IP address %s", ipstr);
    
    if ((hp = gethostbyaddr((const void *)&ip, sizeof ip, AF_INET)) == NULL)
            errx(1, "no name associated with %s", ipstr);
    
     printf("name associated with %s is %s\n", ipstr, hp->h_name);
    

如何进一步检查以确定出错的地方?

如果您使用gethostbyaddr返回NULL,则应通过查看变量h_errno来检查出现了什么问题。

h_errno可以具有以下定义的值之一:

  1. HOST_NOT_FOUND
  2. TRY_AGAIN
  3. NO_RECOVERY
  4. NO_DATA
  5. 有关此问题的详细信息,请参阅您的手册。


    <击> 您的摘要完全错误..

    你提供的片段甚至都没有编译,但是你在某种程度上表明了你想要完成的事情,但我无法确定这一点。 这篇文章包含应被视为“有根据的猜测”的详细信息。

    OP改变了他的职位..

答案 1 :(得分:2)

每当发生某些错误时,

gethostbyaddr都会返回空指针。错误可能是错误的IP地址,未知主机,错误配置的DNS设置等。您需要检查实际的错误代码。在Winsock上,这意味着调用WSAGetLastError,而在POSIX上(我认为)你需要检查h_errno的值。 (我在POSIX上错了,我没有经验)

答案 2 :(得分:1)

    class CIPManager
{
public:
    CIPManager()
    {
        WSADATA wsaData;
        int iResult;
        iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (iResult != 0) {
            printf("WSAStartup failed: %d\n", iResult);
            //return 1;
        }
    }

    bool getPCName(unsigned long ip,char* hostname)//string& strIP)
    {
        DWORD dwRetval;
        //char hostname[NI_MAXHOST];
        char servInfo[NI_MAXSERV];
        u_short port = 27015;
        //hostname=NULL;

        // Validate the parameters
        /*if (argc != 2) {
            printf("usage: %s IPv4 address\n", argv[0]);
            printf("  to return hostname\n");
            printf("       %s 127.0.0.1\n", argv[0]);
            return 1;
        }*/
        // Initialize Winsock
        /*
        */
        //-----------------------------------------
        // Set up sockaddr_in structure which is passed
        // to the getnameinfo function
        saGNI.sin_family = AF_INET;
        saGNI.sin_addr.s_addr =ip;// inet_addr(strIP);
        saGNI.sin_port = htons(port);

        //-----------------------------------------
        // Call getnameinfo
        dwRetval = getnameinfo((struct sockaddr *) &saGNI,
            sizeof (struct sockaddr),
            hostname,
            NI_MAXHOST, servInfo, 
            NI_MAXSERV, NI_NUMERICSERV);

        if (dwRetval != 0) {
            printf("getnameinfo failed with error # %ld\n", WSAGetLastError());
            //return 1;
            return NULL;
        } else {
        //  printf("getnameinfo returned hostname = %s\n", hostname);
            //return hostname;
            return 1;
        }
    }

protected:
private:
    struct sockaddr_in saGNI;

};

使用 getnameinfo 是更好的解决方案!