C++ cross platform resolve hostname to ip library

Started by
2 comments, last by TheComet 8 years, 8 months ago

As the title says, I'm thinking about using a small library to do just that: resolve a hostname to an ip address, without having me to rewrite the code for windows & linux.

Anyonw have recommendations for a smaller simple lib to achieve that?

Advertisement
This one looks reasonable: http://25thandclement.com/~william/projects/dns.c.html

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Only problem with that one is that it's limited to the POSIX OSes (and MingW for nominal Windows support, but anyone who considers compiling on MingW to be "ported to Windows" should be thrown out of a window).

I don't know any particular good library for this, other than just using the standard POSIX/Winsock function getaddrinfo.

Sean Middleditch – Game Systems Engineer – Join my team!

As SeanMiddleditch pointed out, getaddrinfo() is probably your best bet. The following is a great guide on socket programming. I used it extensively as a reference when I was learning about sockets.

http://beej.us/guide/bgnet/output/print/bgnet_A4.pdf

If you scroll down to page 20 (16) (Chapter 5.1. getaddrinfo()) there's a complete example which does exactly what you asked for.

You may have to adjust a few things here and there to get it working on Windows (e.g. call WSAStartup() and WSACleanup() and include the right headers), but by and large it works the same way on Windows.


anyone who considers compiling on MingW to be "ported to Windows" should be thrown out of a window

Can you elaborate some more on why you take this stance?

I've come to the conclusion that writing cross platform software is a lot easier for everyone if you drop support for the MSVC compiler. It's non-compliant in many areas and is a pain to configure properly. As such it only causes headaches and additional overhead when writing your build scripts.

I find it disappointing that porting an entire POSIX compliant environment and toolchain to Windows is easier to do than supporting the MSVC compiler, but that's how it is.

EDIT:

Just got the code from the PDF file I linked to work using MSVC:


#include <stdio.h>
#include <string.h>
#include <WinSock2.h>
#include <WS2tcpip.h>  // INET6_ADDRSTRLEN

static WSADATA g_wsa_data;

char net_init(void)
{
    return (WSAStartup(MAKEWORD(2, 2), &g_wsa_data) == NO_ERROR);
}

void net_deinit(void)
{
    WSACleanup();
}

void net_dns_resolve(const char* hostname)
{
    struct addrinfo hints, *results, *item;
    int status;
    char ipstr[INET6_ADDRSTRLEN];

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;  /* AF_INET6 to force version */
    hints.ai_socktype = SOCK_STREAM;

    if((status = getaddrinfo(hostname, NULL, &hints, &results)) != 0)
    {
        fprintf(stderr, "failed to resolve hostname \"%s\": %s", hostname, gai_strerror(status));
        return;
    }

    printf("IP addresses for %s:\n\n", hostname);

    for(item = results; item != NULL; item = item->ai_next)
    {
        void* addr;
        char* ipver;

        /* get pointer to the address itself */
        /* different fields in IPv4 and IPv6 */
        if(item->ai_family == AF_INET)  /* address is IPv4 */
        {
            struct sockaddr_in* ipv4 = (struct sockaddr_in*)item->ai_addr;
            addr = &(ipv4->sin_addr);
            ipver = "IPv4";
        }
        else  /* address is IPv6 */
        {
            struct sockaddr_in6* ipv6 = (struct sockaddr_in6*)item->ai_addr;
            addr = &(ipv6->sin6_addr);
            ipver = "IPv6";
        }

        /* convert IP to a string and print it */
        inet_ntop(item->ai_family, addr, ipstr, sizeof ipstr);
        printf("  %s: %s\n", ipver, ipstr);
    }

    freeaddrinfo(results);
}

int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        fprintf(stderr, "usage: %s <hostname>\n", argv[0]);
        return -1;
    }

    net_init();
    net_dns_resolve(argv[1]);
    net_deinit();

    return 0;
}

Don't forget to link Ws2_32.lib under Configuration Properties->Linker->Input.

Here's the code ported to Linux:


#include <stdio.h>
#include <string.h>
#include <sys/socket.h> 
#include <netdb.h>




char net_init(void)
{
    return 1; /* nothing to do */
}


void net_deinit(void)
{
    /* nothing to do */
}


void net_dns_resolve(const char* hostname)
{
    struct addrinfo hints, *results, *item;
    int status;
    char ipstr[INET6_ADDRSTRLEN];


    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;  /* AF_INET6 to force version */
    hints.ai_socktype = SOCK_STREAM;


    if((status = getaddrinfo(hostname, NULL, &hints, &results)) != 0)
    {
        fprintf(stderr, "failed to resolve hostname \"%s\": %s", hostname, gai_strerror(status));
        return;
    }


    printf("IP addresses for %s:\n\n", hostname);


    for(item = results; item != NULL; item = item->ai_next)
    {
        void* addr;
        char* ipver;


        /* get pointer to the address itself */
        /* different fields in IPv4 and IPv6 */
        if(item->ai_family == AF_INET)  /* address is IPv4 */
        {
            struct sockaddr_in* ipv4 = (struct sockaddr_in*)item->ai_addr;
            addr = &(ipv4->sin_addr);
            ipver = "IPv4";
        }
        else  /* address is IPv6 */
        {
            struct sockaddr_in6* ipv6 = (struct sockaddr_in6*)item->ai_addr;
            addr = &(ipv6->sin6_addr);
            ipver = "IPv6";
        }


        /* convert IP to a string and print it */
        inet_ntop(item->ai_family, addr, ipstr, sizeof ipstr);
        printf("  %s: %s\n", ipver, ipstr);
    }


    freeaddrinfo(results);
}


int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        fprintf(stderr, "usage: %s <hostname>\n", argv[0]);
        return -1;
    }


    net_init();
    net_dns_resolve(argv[1]);
    net_deinit();


    return 0;
}
"I would try to find halo source code by bungie best fps engine ever created, u see why call of duty loses speed due to its detail." -- GettingNifty

This topic is closed to new replies.

Advertisement