无法使getnameinfo处理我的UDP代码

时间:2015-01-18 08:29:21

标签: c++ linux sockets udp

我有以下UDP客户端通信代码:

clUDPPort::clUDPPort(int prt,string hostname){ //client
nServerPort = prt;
szHostName = hostname;  
nSocketId = socket (AF_INET , SOCK_DGRAM, 0 ) ;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(nServerPort) ; 
host = gethostbyname(szHostName.c_str()) ;
memcpy( (char*)&serverAddr.sin_addr,(char*) host->h_addr , host->h_length ) ;
//nSize = sizeof(serverAddr);
}

此代码是嵌入式Linux设备上安装的CGI应用程序的一部分。在我的PC上进行测试时,主机名作为本地地址传递,如192.168.2.50,当部署到设备时,主机名为127.0.0.1,因为我的应用程序连接了一个服务程序。

问题是链接警告说:

/home/abdalla/XML_Communication/udpport.cpp:24: warning: gethostbyname is obsolescent, use getnameinfo() instead.

这是由openSUSE 13.2 64位上的KDevelop 4.7生成的。我试图使用getnameinfo,但无法弄清楚如何使其工作,因为根据documentation它要求主机名和服务器名称。显然在我的代码中主机和服务器是相同的。你能帮助我让getnameinfo为我的代码工作吗?感谢。

2 个答案:

答案 0 :(得分:1)

将名称翻译成地址实际需要的是getaddrinfo。有关包含示例代码的详细信息,请参阅linux man page

答案 1 :(得分:0)

这是我使用getaddrinfo()的代码。

///the common socket address. we will use this structure to describe all Internet address.
struct nw_sockaddr_t
{
    struct sockaddr addr;   //currently 16 bytes
    unsigned int addrlen;
};
bool nw_sock_addr_fill(nw_sockaddr_t& addr, const char* node, const char* service)
{
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = addr.addr.sa_family;
    hints.ai_socktype = SOCK_STREAM;
    struct addrinfo* ai = NULL, *ai_o = NULL;
    bool good = false;
    do
    {
        if(0!=getaddrinfo(node, service, &hints, &ai))
            break;
        ai_o = ai;
        if(NULL!=ai)
        {
            if(NULL==ai->ai_next)
            {
                memcpy(&addr.addr, ai->ai_addr, sizeof(addr.addr));
                addr.addrlen = ai->ai_addrlen;
                good = true;
            }
            else
            {
                while(NULL!=ai->ai_next)
                {
                    if(ai->ai_family==AF_INET || ai->ai_family==AF_INET6)
                        break;
                    ai = ai->ai_next;
                }
                if(NULL!=ai)
                    ai = ai_o;
                memcpy(&addr.addr, ai->ai_addr, sizeof(addr.addr));
                addr.addrlen = ai->ai_addrlen;
                good = true;
            }
        }
    }while(false);
    if(NULL!=ai_o)
        freeaddrinfo(ai_o);
    if(good)
    {
        if(AF_INET==addr.addr.sa_family)
        {
            struct sockaddr_in* in = (sockaddr_in*)(&addr.addr);
            if(0==in->sin_port)
                in->sin_port = htons(ut_n2u32(service, strlen(service)));
        }
        else if(AF_INET6==addr.addr.sa_family)
        {
            struct sockaddr_in6* in = (sockaddr_in6*)(&addr.addr);
            if(0==in->sin6_port)
                in->sin6_port = htons(ut_n2u32(service, strlen(service)));
        }
    }
    return good;
}

用法:

nw_sockaddr_t addr;
if(nw_sock_addr_fill(addr, "127.0.0.1", "80"))
{
    //here you will get the ipv4 address
    struct sockaddr_in* addr_in = (struct sockaddr_in*)(&addr.addr);
}