How to use getaddrinfo()?

12,770

Solution 1

What if i leave the third parameter nullified?

Heres the code i developed so far.

    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 is declared elsewhere that i use to fill a socket in another method of my sockets class.

Solution 2

The MSDN documentation is very detailed and explains exactly what the various parameters are for. The third parameter lets you specify the type of socket that will be used with the results of the lookup. This allies the results to be optimized as needed. The fourth parameter returns the actual results. The documentation also contains a full example of how to use the function. So what example is unclear about what the documentation says?

Try this:

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);
    }
}
Share:
12,770
Kelvin
Author by

Kelvin

Updated on June 23, 2022

Comments

  • Kelvin
    Kelvin almost 2 years

    Im trying to make a simple program that takes in a string like www.google.com and returns the ip address...

    What i have so far:

    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;
    

    What are the 3rd of 4th parameters supposed to do? Does the getaddrinfo function modify the new_addr structure or what? I dont really understand the msdn documentation. After the hostname is resolved I want to connect a socket to it.

  • Kelvin
    Kelvin about 11 years
    hints.ai_flags = 0; hints.ai_family = AF_UNSPEC; // IPv4 and IPv6 allowed hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; So the hints structure acts as a guiding tool for the getaddrinfo function?
  • Kelvin
    Kelvin about 11 years
    The hints thing was what is confusing me. Its supposed to act as a guiding tool for the getaddr function, but in reality, doesnt get modified right?
  • Remy Lebeau
    Remy Lebeau about 11 years
    @Kelvin: No, the contents of the third parameter do not get modified. It simply tells the function what type of socket the results will be used with, how to perform the name resolution, etc. Behavioral qualities that tell the function WHAT to do. The last parameter is what allocates and returns the actual results of the lookup. Why is that so hard to understand?
  • Kelvin
    Kelvin about 11 years
    I see. For the res, it is just a pointer, i was reading that it will point to a NEW addrinfo structure. And from there you can use res for the results. So i assume that the function makes a new or mallocs a get addrinfo with res pointing to it right? Im going to take a look for the source code of this function and see if i can see how it works better. Thanks for your help. If you want to see, I am making a class for sockets for my personal use.I still gotta update it tho. bitbucket.org/kelvinsilva/keyclient-project/src/…
  • Remy Lebeau
    Remy Lebeau about 11 years
    Yes, the function allocates a linked list of addrinfo structures for its output. You use freeaddrinfo() to free that list when you are finished using it.
  • TheRealChx101
    TheRealChx101 almost 8 years
    Your code has typos and logic errors. Please review it
  • Remy Lebeau
    Remy Lebeau almost 8 years
    @chx101: the only typo I see is freeaddrinof should have been freeaddrinfo instead. I have fixed that. But aside from that, the code as shown compiles and runs fine for me. I do not see any logic errors, where do you think they are?