• 网络编程之基本函数一


     

    hostent *gethostbyname(const char *name);
        这个函数的传入值是域名或者主机名,例如"www.google.cn"等等。传出值,是一个hostent的结构。如果函数调用失败,将返回NULL。

     struct hostent
        {
            char    *h_name;               
            char    **h_aliases;
            int     h_addrtype;
            int     h_length;
            char    **h_addr_list;
            #define h_addr h_addr_list[0]
        };

        hostent->h_name
        表示的是主机的规范名。例如www.google.com的规范名其实是www.l.google.com。
        hostent->h_aliases
        表示的是主机的别名.www.google.com就是google他自己的别名。有的时候,有的主机可能有好几个别名,这些,其实都是为了易于用户记忆而为自己的网站多取的名字。
        hostent->h_addrtype
        表示的是主机ip地址的类型,到底是ipv4(AF_INET),还是pv6(AF_INET6)
        hostent->h_length
        表示的是主机ip地址的长度
        hostent->h_addr_list
        表示的是主机的ip地址,注意,这个是以网络字节序存储的。不能直接用printf带%s参数来打印,所以到真正需要打印出这个IP的话,需要调用inet_ntop()。

        linux 下可以调用const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) :
        这个函数,是将类型为af的网络地址结构src,转换成主机序的字符串形式,存放在长度为cnt的字符串中。返回指向dst的一个指针。如果函数调用错误,返回值是NULL。

    以下是简单的例子:

       因为windows中没有inet_ntop函数可以使用,所以必须重写这个函数,幸亏有人已经做过这样的事情。

    // PrintAddress.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    #include <WinSock.h>
    #include <iostream>
    
    using namespace std;
    #pragma comment(lib,"ws2_32.lib")
    
    #define IN6ADDRSZ 128
    #define INT16SZ   16
    #define INET6_ADDRSTRLEN 128
    
    #ifdef _WIN32
    
    typedef struct _BASE 
    {
        long base;
        long len;
    }BASE;
    
    static const char* inet_ntop4(const u_char* src, char* dst, size_t size)
    {
        static const char fmt[] = "%u.%u.%u.%u";
        char tmp[sizeof("255.255.255.255")];
    
        int l = sprintf_s(tmp,"%d.%d.%d.%d", src[0], src[1], src[2], src[3]);
        if(l <= 0 ||l >size)
        {
            return NULL;
        }
    
        strcpy_s(dst, size, tmp);
        return dst;
    }
    
    static const char* inet_ntop6(const u_char* src, char* dst, size_t size)
    {
        /* Note that int32_t and int16_t need only be "at least" large enough
    
        * to contain a value of the specified size.  On some systems, like
    
        * Crays, there is no such thing as an integer variable with 16 bits.
    
        * Keep this in mind if you think this function should have been coded
    
        * to use pointer overlays.  All the world's not a VAX. */
    
        char  tmp [INET6_ADDRSTRLEN+1];
        char *tp;
        BASE best, cur;
        u_long words [IN6ADDRSZ / INT16SZ];
        int    i;
    
    
        /* Preprocess:
    
        *  Copy the input (bytewise) array into a wordwise array.
    
        *  Find the longest run of 0x00's in src[] for :: shorthanding. */
    
        memset (words, 0, sizeof(words));
    
        for (i = 0; i < IN6ADDRSZ; i++)
        {
            words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
        }
    
        best.base = -1;
        cur.base  = -1;
    
        for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
        {
            if (words[i] == 0)
            {
                if (cur.base == -1)
                {
                    cur.base = i, cur.len = 1;
                }
                else cur.len++;
            }
            else if (cur.base != -1)
            {
                if (best.base == -1 || cur.len > best.len)
                {
                    best = cur;
                }
                cur.base = -1;
            }
    
        }
        if ((cur.base != -1) && (best.base == -1 || cur.len > best.len))
        {
            best = cur;
        }
        if (best.base != -1 && best.len < 2)
        {
            best.base = -1;
        }
    
        /* Format the result. */
        tp = tmp;
        for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
        {
            /* Are we inside the best run of 0x00's? */
            if (best.base != -1 && i >= best.base && i < (best.base + best.len))
            {
                if (i == best.base)
                {
                    *tp++ = ':';
                }
                continue;
            }
            /* Are we following an initial run of 0x00s or any real hex? */
            if (i != 0)
            {
                *tp++ = ':';
            }
            /* Is this address an encapsulated IPv4?*/
            if (i == 6 && best.base == 0 &&(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
            {
                tp += strlen(tp);
                break;
            }
            tp += sprintf (tp, "%lX", words[i]);
        }
    
        /* Was it a trailing run of 0x00's?  */
        if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
        {
            *tp++ = ':';
        }
        *tp++ = '\0';
    
    
        /* Check for overflow, copy, and we're done.
    
        */
    
        if ((size_t)(tp - tmp) > size)
        {
            return NULL;
        }
        strcpy_s(dst, size, tmp);
        return dst;
    }
    
    const char* inet_ntop(int af, void *src, char *dst, size_t size)
    
    {
        switch (af) 
        {
        case AF_INET :
            return inet_ntop4 ((u_char*)src, dst, size);
    #ifdef INET6
        case AF_INET6:
            return inet_ntop6 ((const u_char*)src, dst, size);
    #endif
        default :
            return NULL;
        }
    } 
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        char str[32];
        char* ip = "www.baidu.com";
    
        WSAData wsaData;
        if(WSAStartup(0x22, &wsaData) != 0)
        {
            return 0;
        }
    
    
        LPHOSTENT host = gethostbyname(ip);
        if(host != NULL)
        {
            cout<<host->h_name<<endl;
            cout<<host->h_length<<endl;
            for(char** ptr = host->h_aliases; *ptr != NULL; ptr++)
            {
                cout<<"Alias:"<<*ptr<<endl;
            }
            for(char** ptr = host->h_addr_list; *ptr != NULL; ptr++)
            {
                cout<<"Address:"<<inet_ntop(AF_INET,ptr, str, sizeof(str))<<endl;
            }
            cout<<"First address:"<<inet_ntop(AF_INET, host->h_addr, str, sizeof(str))<<endl;
        }
        system("pause");
        return 0;
    }
    #endif

    输出结果为:

    image

     

  • 相关阅读:
    SpringCloud06Config远程配置
    SpringCloud05Zuul网关
    SpringCloud02Ribbon负载均衡
    Springboot06Dubbo+Zookeeper
    SpringCloud03Feign负载均衡
    @SpringbootApllication主启动类注解分析
    SpringCloud04Hystrix熔断机制
    SpringCloud01Eureka注册中心
    Redis笔记
    C++while循环特殊用法
  • 原文地址:https://www.cnblogs.com/leven20061001/p/2796520.html
Copyright © 2020-2023  润新知