• 网络编程IP帮助函数


    http://www.cnblogs.com/Clingingboy/archive/2011/06/21/2086348.html

    一.GetNetworkParams获取本地电脑的网络参数

    获取一个FIXED_INFO的结构体

    typedef struct {
        char HostName[MAX_HOSTNAME_LEN + 4] ;
        char DomainName[MAX_DOMAIN_NAME_LEN + 4];
        PIP_ADDR_STRING CurrentDnsServer;
        IP_ADDR_STRING DnsServerList;
        UINT NodeType;
        char ScopeId[MAX_SCOPE_ID_LEN + 4];
        UINT EnableRouting;
        UINT EnableProxy;
        UINT EnableDns;
    } FIXED_INFO_W2KSP1, *PFIXED_INFO_W2KSP1;
    #if (NTDDI_VERSION >= NTDDI_WIN2KSP1)
    typedef  FIXED_INFO_W2KSP1 FIXED_INFO;
    typedef  FIXED_INFO_W2KSP1 *PFIXED_INFO;
    #endif
    

    二.网络接口管理

    1.GetNumberOfInterfaces获取接口数量

    DWORD GetNumberOfInterfaces(
      __out  PDWORD pdwNumIf
    );

    2.GetAdaptersInfo返回本地网络适配器列表

    DWORD GetAdaptersInfo(
      __out    PIP_ADAPTER_INFO pAdapterInfo,
      __inout  PULONG pOutBufLen
    );

    int main()
    {
        PIP_INTERFACE_INFO pInfo = 
                (PIP_INTERFACE_INFO)::GlobalAlloc(GPTR, sizeof(IP_INTERFACE_INFO));
        ULONG ulOutBufLen = sizeof(IP_INTERFACE_INFO);
    
        // 如果上面申请的内存不够的话,再重新申请
        if(::GetInterfaceInfo(pInfo, &ulOutBufLen) == ERROR_INSUFFICIENT_BUFFER)
        {
            ::GlobalFree(pInfo);
            pInfo = (PIP_INTERFACE_INFO)::GlobalAlloc(GPTR, ulOutBufLen);
        }
    
        // 再次调用GetInterfaceInfo来获取我们实际需要的数据
        if(::GetInterfaceInfo(pInfo, &ulOutBufLen) == NO_ERROR)
        {
            printf(" \tAdapter Name: %ws\n", pInfo->Adapter[0].Name);
            printf(" \tAdapter Index: %ld\n", pInfo->Adapter[0].Index);
            printf(" \tNum Adapters: %ld\n", pInfo->NumAdapters);
        }
        else
        {
            printf(" GetInterfaceInfo() failed \n");
        }
    
        ::GlobalFree(pInfo);
        return 0;
    }
    

    三.IP地址管理

    获取IP地址列表、添加和删除IP地址
    GetIpAddrTable、AddIPAddress、DeleteIPAddress

    int main()
    {
            // 首先调用GetIpAddrTable函数获取一个适配器
        PMIB_IPADDRTABLE pIPAddrTable;
        DWORD dwSize = 0;
    
        pIPAddrTable = (PMIB_IPADDRTABLE)::GlobalAlloc(GPTR, sizeof(MIB_IPADDRTABLE));
    
        // 获取所需的内存
        if(::GetIpAddrTable(pIPAddrTable, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
        {
            ::GlobalFree(pIPAddrTable);
            pIPAddrTable = (PMIB_IPADDRTABLE)::GlobalAlloc(GPTR, dwSize);
        }
    
        // 再次调用GetIpAddrTable获取实际我们想要的数据
        if(::GetIpAddrTable(pIPAddrTable, &dwSize, FALSE) == NO_ERROR)
        {
            // 打印出适配器信息
            printf(" Address: %ld\n", pIPAddrTable->table[0].dwAddr);
            printf(" Mask:    %ld\n", pIPAddrTable->table[0].dwMask);
            printf(" Index:   %ld\n", pIPAddrTable->table[0].dwIndex);
            printf(" BCast:   %ld\n", pIPAddrTable->table[0].dwBCastAddr);
            printf(" Reasm:   %ld\n", pIPAddrTable->table[0].dwReasmSize);
        }    
        else
        {
            printf(" GetIpAddrTable() failed \n");
        }
        
        ::GlobalFree(pIPAddrTable);
        
        // 我们将要添加的IP和mast
        UINT iaIPAddress;
        UINT imIPMask;
        
        iaIPAddress = inet_addr("192.168.0.27");
        imIPMask = inet_addr("255.255.255.0");
        
        // 返回的句柄
        ULONG NTEContext = 0;
        ULONG NTEInstance = 0;
        
        // 向第一个适配器添加IP地址
        DWORD dwRet;
        dwRet = ::AddIPAddress(iaIPAddress, imIPMask, 
                    pIPAddrTable->table[0].dwIndex, &NTEContext, &NTEInstance);
        if(dwRet == NO_ERROR) 
        {
            printf(" IP address added.\n");
        }
        else 
        {
            printf(" AddIPAddress failed. \n");
            LPVOID lpMsgBuf;
            // 调用失败,打印出为什么失败
            if (::FormatMessage( 
                FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                FORMAT_MESSAGE_FROM_SYSTEM | 
                FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                dwRet,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                (LPTSTR) &lpMsgBuf,
                0,
                NULL )) 
            {
                printf(" Error: %s ", lpMsgBuf);
            }
            ::LocalFree(lpMsgBuf);
        }
        
        // 删除上面在第一个适配器上添加的IP地址
        dwRet = ::DeleteIPAddress(NTEContext);
        if(dwRet == NO_ERROR) 
        {
            printf(" IP Address Deleted.\n");
        }
        else 
        {        
            printf(" DeleteIPAddress failed.\n");
        }
        
        return 0;
    }
    

    四.获取网络状态信息

    1.获取TCP和UDP连接表(GetTcpTable,GetUdpTable)

    PMIB_UDPTABLE MyGetUdpTable(BOOL bOrder)
    {
        PMIB_UDPTABLE pUdpTable = NULL;
        DWORD dwActualSize = 0;
    
        // 查询所需缓冲区的大小
        if(::GetUdpTable(pUdpTable, &dwActualSize, bOrder) == ERROR_INSUFFICIENT_BUFFER)
        {
            // 为MIB_UDPTABLE结构申请内存
            pUdpTable = (PMIB_UDPTABLE)::GlobalAlloc(GPTR, dwActualSize);
            // 获取UDP监听表
            if(::GetUdpTable(pUdpTable, &dwActualSize, bOrder) == NO_ERROR)
                return pUdpTable;
            ::GlobalFree(pUdpTable);
        }
        return NULL;
    }
    
    void MyFreeUdpTable(PMIB_UDPTABLE pUdpTable)
    {
        if(pUdpTable != NULL)
            ::GlobalFree(pUdpTable);
    }
    
    // 打印UDP监听表信息
    PMIB_UDPTABLE pUdpTable = MyGetUdpTable(TRUE);
    if(pUdpTable != NULL)
    {
        struct in_addr inadLocal;
        printf("UDP TABLE\n");
    
        printf("%20s %10s\n", "Loc Addr", "Loc Port");
        for (UINT i = 0; i < pUdpTable->dwNumEntries; ++i)
        {
            inadLocal.s_addr = pUdpTable->table[i].dwLocalAddr;
            // 打印出此入口的信息
            printf("%20s %10u \n", 
                inet_ntoa(inadLocal), ntohs((unsigned short)(0x0000FFFF & pUdpTable->table[i].dwLocalPort)));
        }
    
        MyFreeUdpTable(pUdpTable);
    }
    



    五.获取相关统计数据

    相关的函数GetxxxStatistics(GetIpStatistics,GetIcmpStatistics,GetTcpStatistics,GetUdpStatistics)

    // 获取UDP统计数据
    MIB_UDPSTATS UdpStats;
    if(::GetUdpStatistics(&UdpStats) == NO_ERROR)
    {
        MIB_UDPSTATS *pStats = &UdpStats;
        printf("\nUDP Statistics\n");
        printf("\
                  dwInDatagrams      = %lu\n\
                  dwNoPorts          = %lu\n\
                  dwInErrors         = %lu\n\
                  dwOutDatagrams     = %lu\n\
                  dwNumAddrs         = %lu\n",
                  pStats->dwInDatagrams,
                  pStats->dwNoPorts,
                  pStats->dwInErrors,
                  pStats->dwOutDatagrams,
                  pStats->dwNumAddrs);
    }
    

    六.路由表管理

    1.GetIpForwardTable获取路由表

    PMIB_IPFORWARDTABLE MyGetIpForwardTable(BOOL bOrder)
    {
        PMIB_IPFORWARDTABLE pIpRouteTab = NULL;
        DWORD dwActualSize = 0;
        
        // 查询所需缓冲区的大小
        if(::GetIpForwardTable(pIpRouteTab, &dwActualSize, bOrder) == ERROR_INSUFFICIENT_BUFFER)
        {
            // 为MIB_IPFORWARDTABLE结构申请内存
            pIpRouteTab = (PMIB_IPFORWARDTABLE)::GlobalAlloc(GPTR, dwActualSize);
            // 获取路由表
            if(::GetIpForwardTable(pIpRouteTab, &dwActualSize, bOrder) == NO_ERROR)
                return pIpRouteTab;
            ::GlobalFree(pIpRouteTab);
        }
        return NULL;
    }
    
    void PrintIpForwardTable()
    {
        PMIB_IPFORWARDTABLE pIpRouteTable = MyGetIpForwardTable(TRUE);
        if(pIpRouteTable != NULL)
        {
            DWORD i, dwCurrIndex;
            struct in_addr inadDest;
            struct in_addr inadMask;
            struct in_addr inadGateway;  
            PMIB_IPADDRTABLE pIpAddrTable = NULL;
            
            char szDestIp[128];
            char szMaskIp[128];
            char szGatewayIp[128];
    
            printf("Active Routes:\n\n");
            
            printf("  Network Address          Netmask  Gateway Address        Interface  Metric\n");
            for (i = 0; i < pIpRouteTable->dwNumEntries; i++)
            {
                dwCurrIndex = pIpRouteTable->table[i].dwForwardIfIndex;
        
                // 目的地址
                inadDest.s_addr = pIpRouteTable->table[i].dwForwardDest;
                // 子网掩码
                inadMask.s_addr = pIpRouteTable->table[i].dwForwardMask;
                // 网关地址
                inadGateway.s_addr = pIpRouteTable->table[i].dwForwardNextHop;
                
                strcpy(szDestIp, inet_ntoa(inadDest));
                strcpy(szMaskIp, inet_ntoa(inadMask));
                strcpy(szGatewayIp, inet_ntoa(inadGateway));
                printf("  %15s %16s %16s %16d %7d\n", 
                    szDestIp, 
                    szMaskIp, 
                    szGatewayIp, 
                    pIpRouteTable->table[i].dwForwardIfIndex,    // 可以在此调用GetIpAddrTable获取索引对应的IP地址
                    pIpRouteTable->table[i].dwForwardMetric1);
            }
            MyFreeIpForwardTable(pIpRouteTable);
        }
    }
    

    2.添加、删除、修改路由

    CreateIpForwardEntry、DeleteIpForwardEntry、SetIpForwardEntry

    七.ARP表管理

    1.获取IP地址到适配器的映射关系,即ARP表(GetIpNetTable)

    BOOL InterfaceIdxToInterfaceIp(PMIB_IPADDRTABLE pIpAddrTable, DWORD dwIndex, char str[])
    {
        char* szIpAddr;
    
        if(pIpAddrTable == NULL ||  str == NULL)
            return FALSE;
        str[0] = '\0';
        // 遍历IP地址表,查找索引dwIndex对应的IP地址
        for(DWORD dwIdx = 0; dwIdx < pIpAddrTable->dwNumEntries; dwIdx++)
        {
            if(dwIndex == pIpAddrTable->table[dwIdx].dwIndex)
            {
                // 以字符串的形式返回查询结果
                szIpAddr = inet_ntoa(*((in_addr*)&pIpAddrTable->table[dwIdx].dwAddr));
                if(szIpAddr)
                {
                    strcpy(str, szIpAddr);
                    return TRUE;
                }
                else
                    return FALSE;
            }
        }
        return FALSE;
    }
    
  • 相关阅读:
    dmesg 时间转换
    [转载]Linux性能测试 ss命令
    [转载]Python高效编程技巧
    [转载]Latency Numbers Every Programmer Should Know
    几道有意思的智力面试题
    单网卡多ip配置
    [转]Office visio 2007 打开后死机,提示关闭
    [转]C++的五种内存存储区
    [转]Linux性能测试 pmap命令
    利用wojilu框架仿一个网站的全过程(Step by Step利用wojilu框架开发网站系列序言)
  • 原文地址:https://www.cnblogs.com/iTaoqi/p/2504104.html
Copyright © 2020-2023  润新知