zoukankan      html  css  js  c++  java
  • Windows Socket Programming 网络编程系列 信息获取

    Structure Introduction

    typedef struct hostent {
    char FAR *h_name;
    char FAR FAR **h_aliases;
    short h_addrtype;
    short h_length;
    char FAR FAR **h_addr_list;
    } HOSTENT, *PHOSTENT, FAR *LPHOSTENT;
    struct sockaddr { 
    unsigned short sa_family;
    char sa_data[14];
    };
    struct sockaddr_in{ 
    short sin_family;
    unsigned short sin_port;
    struct in_addr sin_addr;
    char sin_zero[8];
    };

    typedef struct addrinfo {
    int ai_flags;
    int ai_family;
    int ai_socktype;
    int ai_protocol;
    size_t ai_addrlen;
    char *ai_canonname;
    struct sockaddr *ai_addr;
    struct addrinfo *ai_next;
    } ADDRINFOA, *PADDRINFOA;
    typedef struct in_addr {
    union {
    struct {
    u_char s_b1,s_b2,s_b3,s_b4;
    } S_un_b;
    struct {
    u_short s_w1,s_w2;
    } S_un_w;
    u_long S_addr;
    } S_un;
    } IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;

    Retrieving Functions

    For getting struct hostent, using gethostbyaddr or gethostbyname. However both gethostbyname and gethostbyaddr are deprecated on Windows Socket 2. we suggest to use getnameinfo or getaddrinfo to retrieve name of the host or ip info. Here is a sample for using gethostbyaddr and getshotbyname.
    char * tgrIP = "192.168.1.107";//"192.168.1.107";
    struct hostent* rmtHost = nullptr;
    if (!isalpha(tgrIP[0]))
    {
    t1 = time(nullptr);
    unsigned int naddr = inet_addr(tgrIP);
    rmtHost = gethostbyaddr((char *)&naddr, 4, AF_INET);
    if (rmtHost == nullptr)
    {
    int errcode = ::WSAGetLastError();
    cerr<<errcode<<endl;
    return -1;
    }
    cout<<"Using "<<time(nullptr) - t1<<" seconds"<<endl;
    cout<<"Official name:"<<rmtHost->h_name<<endl;
    char ** pAlias;
    for (pAlias = rmtHost->h_aliases; *pAlias != nullptr; pAlias++)
    cout<<"length:"<<rmtHost->h_length<<endl;
    cout<<"aliases:"<<rmtHost->h_aliases<<endl;
    cout<<"addrtype:"<<rmtHost->h_addrtype<<endl;
    if (rmtHost->h_addrtype == AF_INET)
    {
    int i = 0;
    while (rmtHost->h_addr_list[i] != nullptr)
    {
    struct in_addr addr;
    addr.S_un.S_addr = *(u_long *)rmtHost->h_addr_list[i];
    cout<<"IP:"<<inet_ntoa(addr)<<endl;
    i++;
    }
    }
    }
    char * tgrName = www.baidu.com;//"192.168.1.107";
    rmtHost = nullptr;
    if (!isalpha(tgrIP[0]))
    {
    t1 = time(nullptr);

    rmtHost = gethostbyname(tgrName);
    if (rmtHost == nullptr)
    {
    int errcode = ::WSAGetLastError();
    cerr<<errcode<<endl;
    return -1;
    }
    cout<<"Using "<<time(nullptr) - t1<<" seconds"<<endl;
    cout<<"Official name:"<<rmtHost->h_name<<endl;
    char ** pAlias;
    for (pAlias = rmtHost->h_aliases; *pAlias != nullptr; pAlias++)
    cout<<"length:"<<rmtHost->h_length<<endl;
    cout<<"aliases:"<<rmtHost->h_aliases<<endl;
    cout<<"addrtype:"<<rmtHost->h_addrtype<<endl;
    if (rmtHost->h_addrtype == AF_INET)
    {
    int i = 0;
    while (rmtHost->h_addr_list[i] != nullptr)
    {
    struct in_addr addr;
    addr.S_un.S_addr = *(u_long *)rmtHost->h_addr_list[i];
    cout<<"IP:"<<inet_ntoa(addr)<<endl;
    i++;
    }
    }
    }
    For gethostbyaddr, it only supports AF_INET, AF_INET6 and AF_NETBIOS. For gethostbyname, it only returns IPv4 decimal-dot format.
    MSDN recommands using getnameinfo to instead of gethostbyaddr. Here is using getnameinfo sample.
    char hostname[NI_MAXHOST] = {0};
    char servInfo[NI_MAXSERV] = {0};
    unsigned short port = 3389;
    struct sockaddr_in sa;
    ZeroMemory(&sa, sizeof(sockaddr_in));
    sa.sin_family = AF_INET;
    sa.sin_addr.S_un.S_addr = inet_addr(tgrIP);
    sa.sin_port = ::htons(port);
    t1 = time(nullptr);
    int iret = ::getnameinfo((sockaddr*)&sa, sizeof(sockaddr),
    hostname, NI_MAXHOST,
    servInfo, NI_MAXSERV,
    NI_NOFQDN);
    if (iret != 0)
    {
    iret = ::WSAGetLastError();
    cerr<<"Failed to GetAddrInfo: "<<gai_strerror(iret)<<" (ErrCode: "<<iret<<")."<<endl;
    return -1;
    }
    cout<<"Using "<<time(nullptr) - t1<<" seconds"<<endl;
    cout<<hostname<<endl;
    cout<<servInfo<<endl;
    MSDN recommands using getaddrinfo to instead of gethostbyname. Here is using getaddrinfo sample.
    int hname2ip(const char * pname)
    {
    struct addrinfo hints, * result = nullptr;
    memset(&hints, 0, sizeof(struct addrinfo));

    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_CANONNAME;

    int ret = getaddrinfo(pname, nullptr, &hints, &result);
    if (ret != 0)
    {
    cerr<<"Error:"<<gai_strerror(ret)<<endl;
    return 1;
    }

    cout<<"Host Name: "<<pname<<endl;
    struct addrinfo * curInfo = nullptr;
    for (curInfo = result; curInfo != nullptr; curInfo = curInfo->ai_next)
    {
    cout<<"IP: "<<inet_ntoa(((struct sockaddr_in *)(curInfo->ai_addr))->sin_addr)<<endl;
    }

    return 0;
    }



     
     


  • 相关阅读:
    提高关键词排名的28个优化技巧
    Web存储机制—sessionStorage,localStorage使用方法
    19个JavaScript简化编码小技巧
    禁止浏览器滚动条滚动,但滚动条可以显示
    H5项目常见问题及注意事项
    利用cookie实现“只弹出一次窗口”的JS代码
    关于JSON.parse在ie6,ie7下未定义的issue
    你真的会使用XMLHttpRequest吗?
    页面内容不足以铺满屏幕高度时,footer居底显示
    CSS box-shadow 属性
  • 原文地址:https://www.cnblogs.com/rogerroddick/p/2918112.html
Copyright © 2011-2022 走看看