简介

在Socket编程的时候,大家需求实时获取大家所必要的IP地址。例如在编写后门的时候,大家也许须要得到实惠的外网IP或内网IP;有时候大家可能要求看清大家取得的是或不是是虚拟机网卡,那时候就需求对每一张网卡上的特性进行分辨。以下小编计算了部分常用的拍卖措施供我们参考。

参考资料:1.
领取网卡音讯方式
              2.
虚拟与物理网卡区分方法

直白以来,好像没有一段正式的代码能提供Android设备此时的IP地址,究其原因,Android设备的网卡可能不仅一个,如蜂窝网卡、WiFi网卡,而且同一个网卡也可能有所持续一个IP地址。基于此,一个Android终端很有可能同时拥有四个IP地址(不只是同时所有IPv4和IPv6地址),比如敞开热点共享蜂窝网络的时候,蜂窝网卡拥有一个IPv4地址来拜访外网,WiFi网卡拥有一个IPv4地址来作为内网的网关。

赢得本机所有IP地址:

string name = Dns.GetHostName();
IPAddress[] ipadrlist = Dns.GetHostAddresses(name);

         那些地址是含有所有网卡(虚拟网卡)的ipv4和ipv6地址。

getifaddrs()和struct ifaddrs的应用,获取本机IP

    ifaddrs结构体定义如下:

 1 struct ifaddrs   
 2 {   
 3     struct ifaddrs  *ifa_next;    /* Next item in list */   
 4     char            *ifa_name;    /* Name of interface */   
 5     unsigned int     ifa_flags;   /* Flags from SIOCGIFFLAGS */   
 6     struct sockaddr *ifa_addr;    /* Address of interface */   
 7     struct sockaddr *ifa_netmask; /* Netmask of interface */   
 8     union   
 9     {   
10         struct sockaddr *ifu_broadaddr; /* Broadcast address of interface */   
11         struct sockaddr *ifu_dstaddr; /* Point-to-point destination address */   
12     } ifa_ifu;   
13     #define              ifa_broadaddr ifa_ifu.ifu_broadaddr   
14     #define              ifa_dstaddr   ifa_ifu.ifu_dstaddr   
15     void            *ifa_data;    /* Address-specific data */   
16 };   

饱含内外网筛选,MAC地址用法大全。 ifa_next指向链表的下一个分子;ifa_name是接口名称,以0结尾的字符串,比如eth0,lo;ifa_flags是接口的标识位(比如当IFF_BROADCAST或IFF_POINTOPOINT设置到此标识位时,影响联合体变量ifu_broadaddr存储广播地址或ifu_dstaddr记录点对点地址);ifa_netmask存储该接口的子网掩码;结构体变量存储广播地址或点对点地址(见括弧介绍ifa_flags);ifa_data存储了该接口协议族的异样新闻,它一般是NULL(一般不关切他)。

    函数getifaddrs(int getifaddrs (struct ifaddrs
**__ifap))获取本地网络接口新闻,将之存储于链表中,链表头结点指针存储于__ifap中带回,函数执行成功重返0,失败再次回到-1,且为errno赋值。
   
很强烈,函数getifaddrs用于获取本机接口信息,比如最登峰造极的取得本机IP地址。

 

C++代码样例

网上比较盛行的收获Android设备IP地址的代码有以下三种,上面大家来挨家挨户分析一下。

拿到本机所有IPV4地址:

string name = Dns.GetHostName();
IPAddress[] ipadrlist = Dns.GetHostAddresses(name);
foreach (IPAddress ipa in ipadrlist)
{
            if (ipa.AddressFamily == AddressFamily.InterNetwork)
            Console.Writeline(ipa.ToString());
}

        若要单单获取ipv4地址,可以用IPAdress.AddressFamily
属性判断:对于 IPv4,重返 InterNetwork;对于 IPv6,返回 InterNetworkV6。

       
但是一旦本机可能有多个ipv4的地点,那什么样收获访问默许网关时使用的网卡IP呢。在CSDN论坛找到了大神的措施,用的是询问本机路由表。

获取本机正在采用的ipv4地址(访问互联网的IP),可别小看,依旧有成百上千必要考虑的:
1.一个总结机有七个网卡,无线的、有线的、还有vmare虚拟的多个网卡。
2.固然唯有一个网卡,可是该网卡配置了N个IP地址.其中还蕴涵ipv6地址。

上面贴一个自我直接使用的办法,它通过询问本机路由表,获取访问默许网关时使用的网卡IP。
用了2年了,屡试不爽。

      /// <summary>
        /// 获取当前使用的IP
        /// </summary>
        /// <returns></returns>
        public static string GetLocalIP()
        {
            string result = RunApp("route", "print",true);
            Match m = Regex.Match(result, @"0.0.0.0\s+0.0.0.0\s+(\d+.\d+.\d+.\d+)\s+(\d+.\d+.\d+.\d+)");
            if (m.Success)
            {
                return m.Groups[2].Value;
            }
            else
            {
                try
                {
                    System.Net.Sockets.TcpClient c = new System.Net.Sockets.TcpClient();
                    c.Connect("www.baidu.com", 80);
                    string ip = ((System.Net.IPEndPoint)c.Client.LocalEndPoint).Address.ToString();
                    c.Close();
                    return ip;
                }
                catch (Exception)
                {
                    return null;
                }
            }
        }

        /// <summary>
        /// 获取本机主DNS
        /// </summary>
        /// <returns></returns>
        public static string GetPrimaryDNS()
        {
            string result = RunApp("nslookup", "",true);
            Match m = Regex.Match(result, @"\d+\.\d+\.\d+\.\d+");
            if (m.Success)
            {
                return m.Value;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 运行一个控制台程序并返回其输出参数。
        /// </summary>
        /// <param name="filename">程序名</param>
        /// <param name="arguments">输入参数</param>
        /// <returns></returns>
        public static string RunApp(string filename, string arguments,bool recordLog)
        {
            try
            {
                if (recordLog)
                {
                    Trace.WriteLine(filename + " " + arguments);
                }
                Process proc = new Process();
                proc.StartInfo.FileName = filename;
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.Arguments = arguments;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.UseShellExecute = false;
                proc.Start();

                using (System.IO.StreamReader sr = new System.IO.StreamReader(proc.StandardOutput.BaseStream, Encoding.Default))
                {
                    //string txt = sr.ReadToEnd();
                    //sr.Close();
                    //if (recordLog)
                    //{
                    //    Trace.WriteLine(txt);
                    //}
                    //if (!proc.HasExited)
                    //{
                    //    proc.Kill();
                    //}
                    //上面标记的是原文,下面是我自己调试错误后自行修改的
                    Thread.Sleep(100);           //貌似调用系统的nslookup还未返回数据或者数据未编码完成,程序就已经跳过直接执行
                                                 //txt = sr.ReadToEnd()了,导致返回的数据为空,故睡眠令硬件反应
                    if (!proc.HasExited)         //在无参数调用nslookup后,可以继续输入命令继续操作,如果进程未停止就直接执行
                    {                            //txt = sr.ReadToEnd()程序就在等待输入,而且又无法输入,直接掐住无法继续运行
                        proc.Kill();
                    }
                    string txt = sr.ReadToEnd();
                    sr.Close();
                    if (recordLog)
                        Trace.WriteLine(txt);
                    return txt;
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex);
                return ex.Message;
            }
        }

大神代码源自帖子:

       

另有一种办法通过用ipconfig来博取:

private void GetIP()  
    {  
        Process cmd = new Process();  
        cmd.StartInfo.FileName = "ipconfig.exe";//设置程序名   
        cmd.StartInfo.Arguments = "/all";  //参数   
 //重定向标准输出   
        cmd.StartInfo.RedirectStandardOutput = true;  
        cmd.StartInfo.RedirectStandardInput = true;  
        cmd.StartInfo.UseShellExecute = false;  
        cmd.StartInfo.CreateNoWindow = true;//不显示窗口(控制台程序是黑屏)   
 //cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;//暂时不明白什么意思   
        /* 
 收集一下 有备无患 
        关于:ProcessWindowStyle.Hidden隐藏后如何再显示? 
        hwndWin32Host = Win32Native.FindWindow(null, win32Exinfo.windowsName); 
        Win32Native.ShowWindow(hwndWin32Host, 1);     //先FindWindow找到窗口后再ShowWindow 
        */  
        cmd.Start();  
        string info = cmd.StandardOutput.ReadToEnd();  
        cmd.WaitForExit();  
        cmd.Close();  
        textBox1.AppendText(info);  
    }

澳门金沙国际 1

那儿就要自己下手看怎么截取了。可参考上边大神怎么样用正则表明式来合营。

linux编程获取本机IP地址的二种方法

那是一项不老聃晰而且尚未多大意思的干活。一个缘由是网络地址的安装相当灵活而且都是允许用户展开个性化设置的,比如一台电脑上可以有多块物理网卡或者虚
拟网卡,一个网卡上得以绑定七个IP地址,用户可以为网卡设置别名,可以重命名网卡,用户电脑所在网络拓扑结构未知,主机名设置是一个可选择并且相同能够为一个统计机绑定三个主机名等,这个音信都会有震慑。脱离了网络连接,单独的网络地址没有其他意义。编程中遇见必须取得统计机IP的现象,应该考虑将这
一选项放到配置文件中,由用户自己来选择。

通过google,编程获取IP地址大约有以下三种思路:
1. 通过gethostname()和gethostbyname()

#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main() {
    char hname[128];
    struct hostent *hent;
    int i;

    gethostname(hname, sizeof(hname));

    //hent = gethostent();
    hent = gethostbyname(hname);

    printf("hostname: %s/naddress list: ", hent->h_name);
    for(i = 0; hent->h_addr_list[i]; i++) {
        printf("%s/t", inet_ntoa(*(struct in_addr*)(hent->h_addr_list[i])));
    }
    return 0;
}

运行:
[whb@jcwkyl c]$ ./local_ip 
hostname: jcwkyl.jlu.edu.cn
address list: 10.60.56.90       


2. 通过枚举网卡,API接口可查看man 7 netdevice

/*代码来自StackOverflow: http://stackoverflow.com/questions/212528/linux-c-get-the-ip-address-of-local-computer */
#include <stdio.h>      
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h> 
#include <string.h> 
#include <arpa/inet.h>

int main (int argc, const char * argv[]) {
    struct ifaddrs * ifAddrStruct=NULL;
    void * tmpAddrPtr=NULL;

    getifaddrs(&ifAddrStruct);

    while (ifAddrStruct!=NULL) {
        if (ifAddrStruct->ifa_addr->sa_family==AF_INET) { // check it is IP4
            // is a valid IP4 Address
            tmpAddrPtr=&((struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;
            char addressBuffer[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
            printf("%s IP Address %s/n", ifAddrStruct->ifa_name, addressBuffer); 
        } else if (ifAddrStruct->ifa_addr->sa_family==AF_INET6) { // check it is IP6
            // is a valid IP6 Address
            tmpAddrPtr=&((struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;
            char addressBuffer[INET6_ADDRSTRLEN];
            inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
            printf("%s IP Address %s/n", ifAddrStruct->ifa_name, addressBuffer); 
        } 
        ifAddrStruct=ifAddrStruct->ifa_next;
    }
    return 0;
}

运行 :
[whb@jcwkyl c]$ ./local_ip2 
lo IP Address 127.0.0.1
eth0 IP Address 10.60.56.90
eth0:1 IP Address 192.168.1.3
lo IP Address ::
eth0 IP Address ::2001:da8:b000:6213:20f:1fff
eth0 IP Address 0:0:fe80::20f:1fff

3. 打开一个对外界服务器的网络连接,通过getsockname()反查自己的IP

 

澳门金沙国际 ,1. 头文件(包涵特征处理函数)

/////////////////////////////////////////
//
// FileName : NetInfoProc.h
// Creator : PeterZ
// Date : 2018-6-21 23:50
// Comment : 网卡信息筛选
// Editor : Visual Studio 2017
//
/////////////////////////////////////////

#pragma once

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <strsafe.h>
#include <WinSock2.h>
#include <Iphlpapi.h>
#include <cstring>

#pragma comment(lib,"Iphlpapi.lib")

using namespace std;

#define REG_ERROR -2
#define NO_PCI -1
#define IS_PCI 0


/**
 * @brief 查看字符串中是否有指定特征串
 * @param source 指向源字符串的指针
 * @param target 指向目标字符串的指针
 */
BOOL IsInString(LPCSTR source, LPCSTR target)
{
    if (source == NULL && target == NULL)
    {
        return false;
    }
    const size_t targetLength = strlen(target);
    const size_t sourceLength = strlen(source);

    if (sourceLength >= targetLength)
    {
        for (int i = 0; i < strlen(source); i++)
        {
            if (i + targetLength > sourceLength)
            {
                return false;
            }
            for (int j = 0; j < targetLength; j++)
            {
                if (*(source + i + j) != *(target + j))
                {
                    break;
                }
                if (j == targetLength - 1)
                {
                    return true;
                }
            }
        }
    }
    return false;
}

/**
 * @brief 获取注册表数据
 * @param hRoot 根键
 * @param szSubKey 子键
 * @param szValueName 数据项名
 * @param szRegInfo 数据
 */
BOOL GetRegInfo(HKEY hRoot, LPCTSTR szSubKey, LPCTSTR szValueName, LPSTR szRegInfo)
{
    HKEY hKey;
    DWORD dwType = REG_SZ;
    DWORD dwLenData = strlen(szRegInfo);
    LONG lRes = RegCreateKeyEx(hRoot, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
    if (lRes != ERROR_SUCCESS)
    {
        if (lRes == 5)
        {
            printf("Please use Administrator Privilege !\n");
        }
        else
        {
            printf("Get Register Info Error! Error Code is ");
            printf("%ld\n", lRes);
        }
        RegCloseKey(hKey);
        RegCloseKey(hRoot);
        return false;
    }
    RegQueryValueEx(hKey, szValueName, 0, &dwType, NULL, &dwLenData);
    lRes = RegQueryValueEx(hKey, szValueName, 0, &dwType, (LPBYTE)szRegInfo, &dwLenData);
    if (lRes != ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        RegCloseKey(hRoot);
        return false;
    }
    RegCloseKey(hKey);
    RegCloseKey(hRoot);
    return true;
}

/**
 * @brief 验证注册信息是否是PCI物理网卡(需要以管理员权限运行程序)
 * @param pIpAdapterInfo 指向网卡数据的指针
 */
int IsPCINetCard(const PIP_ADAPTER_INFO pIpAdapterInfo)
{
    //通过注册表特征去除非物理网卡
    CHAR szRegSubKey[255] = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
    CHAR szNetCardRegInfo[255] = "\0";
    StringCchCat(szRegSubKey, sizeof(szRegSubKey), pIpAdapterInfo->AdapterName);
    StringCchCat(szRegSubKey, sizeof(szRegSubKey), "\\Connection");
    if (!GetRegInfo(HKEY_LOCAL_MACHINE, szRegSubKey, "PnPInstanceId", szNetCardRegInfo))
    {
        return REG_ERROR;
    }
    if (strncmp(szNetCardRegInfo, "PCI", 3) == 0) return IS_PCI;
    else return NO_PCI;

}


/**
 * @brief 验证是否是虚拟网卡
 * @param pIpAdapterInfo 指向网卡数据的指针
 */
BOOL IsVirtualNetCard(const PIP_ADAPTER_INFO pIpAdapterInfo)
{
    //去除有特征名的虚拟网卡
    if (IsInString(strlwr(pIpAdapterInfo->Description), "virtual")) return true;
    //去除有MAC的虚拟网卡 vmware
    if (pIpAdapterInfo->Address[0] == 0x00 && pIpAdapterInfo->Address[1] == 0x05 && pIpAdapterInfo->Address[2] == 0x69) return true;
    //去除有MAC的虚拟网卡 vmware
    if (pIpAdapterInfo->Address[0] == 0x00 && pIpAdapterInfo->Address[1] == 0x0C && pIpAdapterInfo->Address[2] == 0x29) return true;
    //去除有MAC的虚拟网卡 vmware
    if (pIpAdapterInfo->Address[0] == 0x00 && pIpAdapterInfo->Address[1] == 0x50 && pIpAdapterInfo->Address[2] == 0x56) return true;
    //去除有MAC的虚拟网卡 vmware
    if (pIpAdapterInfo->Address[0] == 0x00 && pIpAdapterInfo->Address[1] == 0x1C && pIpAdapterInfo->Address[2] == 0x14) return true;
    //去除有MAC的虚拟网卡 parallels
    if (pIpAdapterInfo->Address[0] == 0x00 && pIpAdapterInfo->Address[1] == 0x1C && pIpAdapterInfo->Address[2] == 0x42) return true;
    //去除有MAC的虚拟网卡 microsoft virtual pc
    if (pIpAdapterInfo->Address[0] == 0x00 && pIpAdapterInfo->Address[1] == 0x03 && pIpAdapterInfo->Address[2] == 0xFF) return true;
    //去除有MAC的虚拟网卡 virtual iron
    if (pIpAdapterInfo->Address[0] == 0x00 && pIpAdapterInfo->Address[1] == 0x0F && pIpAdapterInfo->Address[2] == 0x4B) return true;
    //去除有MAC的虚拟网卡 red hat xen , oracle vm , xen source, novell xen
    if (pIpAdapterInfo->Address[0] == 0x00 && pIpAdapterInfo->Address[1] == 0x16 && pIpAdapterInfo->Address[2] == 0x3E) return true;
    //去除有MAC的虚拟网卡 virtualbox
    if (pIpAdapterInfo->Address[0] == 0x08 && pIpAdapterInfo->Address[1] == 0x00 && pIpAdapterInfo->Address[2] == 0x27) return true;
    return false;
}


/**
 * @brief 验证是否是0.0.0.0不可用IP
 * @param pIpAdapterInfo 指向网卡数据的指针
 */
BOOL IsInvalidIp(const PIP_ADAPTER_INFO pIpAdapterInfo)
{
    IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList);
    do
    {
        if (!strcmp(pIpAddrString->IpAddress.String, "0.0.0.0"))
        {
            return false;
        }
        if ((pIpAddrString = pIpAddrString->Next) == NULL)
        {
            return true;
        }
    } while (pIpAddrString);
    return true;
}

/**
* @brief 验证是否是内网IP
* @param pIpAdapterInfo 指向网卡数据的指针
*/
BOOL IsIntranetIP(const PIP_ADAPTER_INFO pIpAdapterInfo)
{
    IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList);
    do
    {
        if (strncmp(pIpAddrString->IpAddress.String, "10", 2) == 0 || (strncmp(pIpAddrString->IpAddress.String, "172.16", 6) > 0 && strncmp(pIpAddrString->IpAddress.String, "172.31", 6) < 0) || strncmp(pIpAddrString->IpAddress.String, "192.168", 7) == 0)
        {
            return true;
        }
        if ((pIpAddrString = pIpAddrString->Next) == NULL)
        {
            return false;
        }
    } while (pIpAddrString);
    return true;
}

1. 不可行的格局

String ipAddress = Inet4Address.getLocalHost().getHostAddress()

其一是Java提供的API,在Android上执行要求以下权限(经测试Android版本6.0.1的一部机器不必要该权限,比较纳闷,求解答)

<uses-permission android:name="android.permission.INTERNET"/>

此外,由于该格局运用了网络通讯,由此不可以在UI线程执行。

该格局顾名思义是收获当地主机的IP地址,在少数Java平台上可以获取想要的结果,可是本人截取了Android官方给出的关于该措施的一对表达如下:

Returns an InetAddress for the local host if possible, or the loopback
address otherwise. This method works by getting the hostname,
performing a DNS lookup, and then taking the first returned address.
Note that if the host doesn’t have a hostname set – as Android devices
typically don’t – this method will effectively return the loopback
address, albeit by getting the name localhost and then doing a lookup
to translate that to 127.0.0.1.

可以看到,一般在Android平台上,由于网络通讯设施尚未设置hostname,因而不可能进展DNS检索获得其相应的IP地址,因而该方法会重返本地回环地址,即127.0.0.1,也就是说那一个方式在Android平台上不能达到大家一般的得到本机IP地址的目标,经过测试,结果也的确那样。

linux下获得IP等音讯函数

 

2. CPP文件(代码应用示范)

/////////////////////////////////////////
//
// FileName : NetCardVer.cpp
// Creator : PeterZ
// Date : 2018-6-21 23:50
// Comment : 网卡信息筛选
// Editor : Visual Studio 2017
//
/////////////////////////////////////////

#include "NetInfoProc.h"

void Output1(PIP_ADAPTER_INFO pIpAdapterInfo); //结果输出1(正常结果)
void Output2(PIP_ADAPTER_INFO pIpAdapterInfo); //结果输出2(删除虚拟网卡的结果)
void Output3(PIP_ADAPTER_INFO pIpAdapterInfo); //结果输出3(去除非PCI物理网卡) >>需要以管理员权限运行程序<<
void Output4(PIP_ADAPTER_INFO pIpAdapterInfo); //结果输出4(筛选内网网卡)

//主函数
int main(void)
{
    PIP_ADAPTER_INFO pIpAdapterInfo = (PIP_ADAPTER_INFO)malloc(sizeof(IP_ADAPTER_INFO));
    unsigned long stSize = sizeof(IP_ADAPTER_INFO);
    int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
    if (ERROR_BUFFER_OVERFLOW == nRel/*GetAdaptersInfo参数传递的内存空间不足*/)
    {
        //free(pIpAdapterInfo);
        pIpAdapterInfo = (PIP_ADAPTER_INFO)realloc(pIpAdapterInfo, stSize);
        nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
    }
    if (ERROR_SUCCESS == nRel)
    {
        printf(">>>>>>>>> 正常结果 <<<<<<<<<<<\n\n");
        Output1(pIpAdapterInfo);
        printf("\n\n>>>>>>>>> 删除虚拟网卡的结果 <<<<<<<<<\n\n");
        Output2(pIpAdapterInfo);
        printf("\n\n>>>>>>>>> 去除非PCI物理网卡的结果 <<<<<<<<<\n\n");
        Output3(pIpAdapterInfo);
        printf("\n\n>>>>>>>>> 筛选内网网卡的结果 <<<<<<<<<\n\n");
        Output4(pIpAdapterInfo);
    }
    if (pIpAdapterInfo)
    {
        free(pIpAdapterInfo);
    }
    system("pause");
    return 0;
}

//结果输出1(正常结果)
void Output1(PIP_ADAPTER_INFO pIpAdapterInfo)
{
    //可能有多网卡,因此通过循环去判断
    while (pIpAdapterInfo)
    {
        //输出信息
        cout << "网卡名称:" << pIpAdapterInfo->AdapterName << endl;
        cout << "网卡描述:" << pIpAdapterInfo->Description << endl;
        cout << "网卡MAC地址:" << pIpAdapterInfo->Address;
        for (UINT i = 0; i < pIpAdapterInfo->AddressLength; i++)
        {
            if (i == pIpAdapterInfo->AddressLength - 1)
            {
                printf("%02x\n", pIpAdapterInfo->Address[i]);
            }
            else
            {
                printf("%02x-", pIpAdapterInfo->Address[i]);
            }
        }
        cout << "网卡IP地址如下:" << endl;
        IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList);
        //可能网卡有多IP,因此通过循环去判断
        do
        {
            cout << pIpAddrString->IpAddress.String << endl;
            pIpAddrString = pIpAddrString->Next;
        } while (pIpAddrString);
        pIpAdapterInfo = pIpAdapterInfo->Next;
        cout << "*****************************************************" << endl;
    }
    return;
}

//结果输出2(删除虚拟网卡的结果)
void Output2(PIP_ADAPTER_INFO pIpAdapterInfo)
{
    //可能有多网卡,因此通过循环去判断
    while (pIpAdapterInfo)
    {
        //去除虚拟网卡IP
        if (IsVirtualNetCard(pIpAdapterInfo))
        {
            pIpAdapterInfo = pIpAdapterInfo->Next;
            continue;
        }
        //输出信息
        cout << "网卡名称:" << pIpAdapterInfo->AdapterName << endl;
        cout << "网卡描述:" << pIpAdapterInfo->Description << endl;
        cout << "网卡MAC地址:" << pIpAdapterInfo->Address;
        for (UINT i = 0; i < pIpAdapterInfo->AddressLength; i++)
        {
            if (i == pIpAdapterInfo->AddressLength - 1)
            {
                printf("%02x\n", pIpAdapterInfo->Address[i]);
            }
            else
            {
                printf("%02x-", pIpAdapterInfo->Address[i]);
            }
        }
        cout << "网卡IP地址如下:" << endl;
        IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList);
        //可能网卡有多IP,因此通过循环去判断
        do
        {
            cout << pIpAddrString->IpAddress.String << endl;
            pIpAddrString = pIpAddrString->Next;
        } while (pIpAddrString);
        pIpAdapterInfo = pIpAdapterInfo->Next;
        cout << "*****************************************************" << endl;
    }
    return;
}

//结果输出3(去除非PCI物理网卡)
void Output3(PIP_ADAPTER_INFO pIpAdapterInfo)
{
    //可能有多网卡,因此通过循环去判断
    while (pIpAdapterInfo)
    {
        //去除非PCI物理网卡
        if (IsPCINetCard(pIpAdapterInfo) != IS_PCI)
        {
            if (IsPCINetCard(pIpAdapterInfo) == REG_ERROR)
            {
                printf("1\n");
                return;
            }
            pIpAdapterInfo = pIpAdapterInfo->Next;
            continue;
        }
        //输出信息
        cout << "网卡名称:" << pIpAdapterInfo->AdapterName << endl;
        cout << "网卡描述:" << pIpAdapterInfo->Description << endl;
        cout << "网卡MAC地址:" << pIpAdapterInfo->Address;
        for (UINT i = 0; i < pIpAdapterInfo->AddressLength; i++)
        {
            if (i == pIpAdapterInfo->AddressLength - 1)
            {
                printf("%02x\n", pIpAdapterInfo->Address[i]);
            }
            else
            {
                printf("%02x-", pIpAdapterInfo->Address[i]);
            }
        }
        cout << "网卡IP地址如下:" << endl;
        IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList);
        //可能网卡有多IP,因此通过循环去判断
        do
        {
            cout << pIpAddrString->IpAddress.String << endl;
            pIpAddrString = pIpAddrString->Next;
        } while (pIpAddrString);
        pIpAdapterInfo = pIpAdapterInfo->Next;
        cout << "*****************************************************" << endl;
    }
    return;
}

//结果输出4(筛选内网网卡)
void Output4(PIP_ADAPTER_INFO pIpAdapterInfo)
{
    //可能有多网卡,因此通过循环去判断
    while (pIpAdapterInfo)
    {
        //筛选内网网卡
        if (!IsIntranetIP(pIpAdapterInfo))
        {
            pIpAdapterInfo = pIpAdapterInfo->Next;
            continue;
        }
        //输出信息
        cout << "网卡名称:" << pIpAdapterInfo->AdapterName << endl;
        cout << "网卡描述:" << pIpAdapterInfo->Description << endl;
        cout << "网卡MAC地址:" << pIpAdapterInfo->Address;
        for (UINT i = 0; i < pIpAdapterInfo->AddressLength; i++)
        {
            if (i == pIpAdapterInfo->AddressLength - 1)
            {
                printf("%02x\n", pIpAdapterInfo->Address[i]);
            }
            else
            {
                printf("%02x-", pIpAdapterInfo->Address[i]);
            }
        }
        cout << "网卡IP地址如下:" << endl;
        IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList);
        //可能网卡有多IP,因此通过循环去判断
        do
        {
            cout << pIpAddrString->IpAddress.String << endl;
            pIpAddrString = pIpAddrString->Next;
        } while (pIpAddrString);
        pIpAdapterInfo = pIpAdapterInfo->Next;
        cout << "*****************************************************" << endl;
    }
    return;
}

2. 片段卓有功能的方法

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
int ipAddressInt = wm.getConnectionInfo().getIpAddress();
String ipAddress = String.format(Locale.getDefault(), "%d.%d.%d.%d", (ipAddressInt & 0xff), (ipAddressInt >> 8 & 0xff), (ipAddressInt >> 16 & 0xff), (ipAddressInt >> 24 & 0xff));

艺术执行所需权限为:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

需求验证的是,上述代码第二行再次来到的是一个int类型的值,如1795336384,它对应的十六进制值6b02a8c0每两位便对应IPv4地址的每一项(逆序,如c0转化为十进制为192)。

经测试,通过该格局可以取得当前WiFi网络中Android设备的IPv4地址,然则显然,该办法是经过WifiManager获取当前网络连接下的IP地址的,由此它只局限于选取WiFi网络的处境,当使用蜂窝等此外网络设施时,该方法行不通,会重临0值。其余,就算您是经过相比较hacker的方式比如没有通过系统Framework层打开WiFi,而是自己通过Linux命令制造的WiFi网络,那么像那种Framework层提供的API也是不起效能的。

在linux下 获取,修改本机IP地址的八个函数

 

//获取本机IP地址函数

 1 QString GetLocalIp()  
 2 {  
 3   
 4     int sock_get_ip;  
 5     char ipaddr[50];  
 6   
 7     struct   sockaddr_in *sin;  
 8     struct   ifreq ifr_ip;     
 9   
10     if ((sock_get_ip=socket(AF_INET, SOCK_STREAM, 0)) == -1)  
11     {  
12          printf("socket create failse...GetLocalIp!/n");  
13          return "";  
14     }  
15      
16     memset(&ifr_ip, 0, sizeof(ifr_ip));     
17     strncpy(ifr_ip.ifr_name, "eth0", sizeof(ifr_ip.ifr_name) - 1);     
18    
19     if( ioctl( sock_get_ip, SIOCGIFADDR, &ifr_ip) < 0 )     
20     {     
21          return "";     
22     }       
23     sin = (struct sockaddr_in *)&ifr_ip.ifr_addr;     
24     strcpy(ipaddr,inet_ntoa(sin->sin_addr));         
25       
26     printf("local ip:%s /n",ipaddr);      
27     close( sock_get_ip );  
28       
29     return QString( ipaddr );  
30 }  

 

//修改本机IP地址的函数

 1 int SetLocalIp( const char *ipaddr )  
 2 {  
 3   
 4     int sock_set_ip;  
 5       
 6     struct sockaddr_in sin_set_ip;  
 7     struct ifreq ifr_set_ip;  
 8   
 9     bzero( &ifr_set_ip,sizeof(ifr_set_ip));  
10    
11     if( ipaddr == NULL )  
12         return -1;  
13   
14     if(sock_set_ip = socket( AF_INET, SOCK_STREAM, 0 ) == -1);  
15     {  
16         perror("socket create failse...SetLocalIp!/n");  
17         return -1;  
18     }  
19    
20     memset( &sin_set_ip, 0, sizeof(sin_set_ip));  
21     strncpy(ifr_set_ip.ifr_name, "eth0", sizeof(ifr_set_ip.ifr_name)-1);     
22       
23     sin_set_ip.sin_family = AF_INET;  
24     sin_set_ip.sin_addr.s_addr = inet_addr(ipaddr);  
25     memcpy( &ifr_set_ip.ifr_addr, &sin_set_ip, sizeof(sin_set_ip));  
26   
27     if( ioctl( sock_set_ip, SIOCSIFADDR, &ifr_set_ip) < 0 )  
28     {  
29         perror( "Not setup interface/n");  
30         return -1;  
31     }  
32   
33     //设置激活标志  
34     ifr_set_ip.ifr_flags |= IFF_UP |IFF_RUNNING;  
35   
36     //get the status of the device  
37     if( ioctl( sock_set_ip, SIOCSIFFLAGS, &ifr_set_ip ) < 0 )  
38     {  
39          perror("SIOCSIFFLAGS");  
40          return -1;  
41     }  
42   
43     close( sock_set_ip );  
44     return 0;  
45 }  

3. 主旨可行的方法

    public static String getIpAddressString() {
        try {
            for (Enumeration<NetworkInterface> enNetI = NetworkInterface
                    .getNetworkInterfaces(); enNetI.hasMoreElements(); ) {
                NetworkInterface netI = enNetI.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = netI
                        .getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (inetAddress instanceof Inet4Address && !inetAddress.isLoopbackAddress()) {
                        return inetAddress.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return "";
    }

主意执行所需权限为:

<uses-permission android:name="android.permission.INTERNET"/>

那段代码不难明白,其实就是再度循环获取极限中所有网络接口的具有IP地址,然后重回第四个蒙受的非本地回环的IPv4地址。那种艺术可以很好的覆盖大家一般的须要。根据Android系统的运行机制,当WiFi网络开启时蜂窝网络会活动关闭,由此遍历到的率先个地方是WiFi网卡的IP地址;同样,当关闭WiFi网络,打开蜂窝网络时,遍历到的首先个地点是蜂窝网卡的IP地址。

那就是说,为啥我叫那种办法为骨干可行的办法吗,因为它回到的结果并不是百分百“正确”的,确切地说并不一定是开发人士想要的结果。比如当Android手机开启热点的时候,实际上是经过WiFi网卡共享其蜂窝网络,由此此时,WiFi网卡和蜂窝网卡分配了差其余IP地址,但出于蜂窝网卡对应的NetworkInterface对象现身的职位要先于WiFi网卡,因而该方法重临的实在是蜂窝网卡的IP地址。如若想要始终得到WiFi网卡的IP地址可以在上述的五个循环间添加如下筛选代码:

if (netI.getDisplayName().equals("wlan0") || netI.getDisplayName().equals("eth0"))

里头”wlan0″和”eth0″为常见的WLAN网卡的DisplayName名称,绝一大半为”wlan0″,相比较老的机型可能会是”eth0″或别的。

此地只是举了一个简短的事例,其实还有很多例外的景色,比如敞开USB网络共享的景观、开启网络代理的图景、以前提到的Hacker手段同时开辟蜂窝网络和WiFi网络(非WiFi热点)的情状等等,那么些网络环境下都会设有多IP的景况,由此该方法不肯定完全适用了。

正如小说初始所说,由于一个Android设备同一时刻或者不唯有一个IP地址,因而可以说没有其它一段通用的代码能获取每个人心中想要获取的IP地址,首要的仍然按照自己实际的急需来拓展对应的代码修改,通过对取得的IP地址列表举办筛选来取得想要的结果。

正文的啄磨是环绕IPv4地址的,假如想要获取IPv6地址,Android
API也提供了相应的类或格局,只须要在上述代码的根基上作出微小修改即可。

最终附上在StackOverFlow上见到的关于IP地址筛选的总计,供我们参考。

  • Any address in the range 127.xxx.xxx.xxx is a “loopback” address.
    It is only visible to “this” host.
  • Any address in the range 192.168.xxx.xxx is a private (aka site
    local) IP address. These are reserved for use within an
    organization. The same applies to 10.xxx.xxx.xxx addresses, and
    172.16.xxx.xxx through 172.31.xxx.xxx.
  • Addresses in the range 169.254.xxx.xxx are link local IP
    addresses. These are reserved for use on a single network segment.
  • Addresses in the range 224.xxx.xxx.xxx through 239.xxx.xxx.xxx are
    multicast addresses.
  • The address 255.255.255.255 is the broadcast address.
  • Anything else should be a valid public point-to-point IPv4
    address.

文中所有代码可以在个人github主页查阅和下载。

另,个体技术博客,同步创新,欢迎关切!转发请讲明出处!文中若有怎样错误希望我们研讨指正!

在linux下 获取本机MAC地址的函数

赢得本机MAC地址函数

 1 QString GetLocalMac()  
 2 {  
 3     int sock_mac;  
 4       
 5     struct ifreq ifr_mac;  
 6     char mac_addr[30];     
 7       
 8     sock_mac = socket( AF_INET, SOCK_STREAM, 0 );  
 9     if( sock_mac == -1)  
10     {  
11         perror("create socket falise...mac/n");  
12         return "";  
13     }  
14       
15     memset(&ifr_mac,0,sizeof(ifr_mac));     
16     strncpy(ifr_mac.ifr_name, "eth0", sizeof(ifr_mac.ifr_name)-1);     
17   
18     if( (ioctl( sock_mac, SIOCGIFHWADDR, &ifr_mac)) < 0)  
19     {  
20         printf("mac ioctl error/n");  
21         return "";  
22     }  
23       
24     sprintf(mac_addr,"%02x%02x%02x%02x%02x%02x",  
25             (unsigned char)ifr_mac.ifr_hwaddr.sa_data[0],  
26             (unsigned char)ifr_mac.ifr_hwaddr.sa_data[1],  
27             (unsigned char)ifr_mac.ifr_hwaddr.sa_data[2],  
28             (unsigned char)ifr_mac.ifr_hwaddr.sa_data[3],  
29             (unsigned char)ifr_mac.ifr_hwaddr.sa_data[4],  
30             (unsigned char)ifr_mac.ifr_hwaddr.sa_data[5]);  
31   
32     printf("local mac:%s /n",mac_addr);      
33       
34     close( sock_mac );  
35     return QString( mac_addr );  
36 }  

在linux下 获取,修改子网掩码NETMASK的七个函数

 

//获取子网掩码的函数

 1 QString GetLocalNetMask()  
 2 {  
 3     int sock_netmask;  
 4     char netmask_addr[50];  
 5   
 6     struct ifreq ifr_mask;  
 7     struct sockaddr_in *net_mask;  
 8           
 9     sock_netmask = socket( AF_INET, SOCK_STREAM, 0 );  
10     if( sock_netmask == -1)  
11     {  
12         perror("create socket failture...GetLocalNetMask/n");  
13         return "";  
14     }  
15       
16     memset(&ifr_mask, 0, sizeof(ifr_mask));     
17     strncpy(ifr_mask.ifr_name, ifname, sizeof(ifr_mask.ifr_name )-1);     
18   
19     if( (ioctl( sock_netmask, SIOCGIFNETMASK, &ifr_mask ) ) < 0 )   
20     {  
21         printf("mac ioctl error/n");  
22         return "";  
23     }  
24       
25     net_mask = ( struct sockaddr_in * )&( ifr_mask.ifr_netmask );  
26     strcpy( netmask_addr, inet_ntoa( net_mask -> sin_addr ) );  
27       
28     printf("local netmask:%s/n",netmask_addr);      
29       
30     close( sock_netmask );  
31     return QString( netmask_addr );  
32 }  

//修改子NETMASK的函数

 1 QString SetLocalNetMask(const char *szNetMask)  
 2 {  
 3     int sock_netmask;  
 4     char netmask_addr[32];     
 5   
 6     struct ifreq ifr_mask;  
 7     struct sockaddr_in *sin_net_mask;  
 8           
 9     sock_netmask = socket( AF_INET, SOCK_STREAM, 0 );  
10     if( sock_netmask == -1)  
11     {  
12         perror("Not create network socket connect/n");  
13         return "";  
14     }  
15       
16     memset(&ifr_mask, 0, sizeof(ifr_mask));     
17     strncpy(ifr_mask.ifr_name, "eth0", sizeof(ifr_mask.ifr_name )-1);     
18     sin_net_mask = (struct sockaddr_in *)&ifr_mask.ifr_addr;  
19     sin_net_mask -> sin_family = AF_INET;  
20     inet_pton(AF_INET, szNetMask, &sin_net_mask ->sin_addr);  
21   
22     if(ioctl(sock_netmask, SIOCSIFNETMASK, &ifr_mask ) < 0)   
23     {  
24         printf("sock_netmask ioctl error/n");  
25         return "";  
26     }  
27 }  

//获去GateWay

 1 QString GetGateWay()  
 2 {  
 3     FILE *fp;  
 4     char buf[512];  
 5     char cmd[128];  
 6     char gateway[30];  
 7     char *tmp;  
 8   
 9     strcpy(cmd, "ip route");  
10     fp = popen(cmd, "r");  
11     if(NULL == fp)  
12     {  
13         perror("popen error");  
14         return "";  
15     }  
16     while(fgets(buf, sizeof(buf), fp) != NULL)  
17     {  
18         tmp =buf;  
19         while(*tmp && isspace(*tmp))  
20             ++ tmp;  
21         if(strncmp(tmp, "default", strlen("default")) == 0)  
22             break;  
23     }  
24     sscanf(buf, "%*s%*s%s", gateway);         
25     printf("default gateway:%s/n", gateway);  
26     pclose(fp);  
27       
28     return QString(gateway);  
29 }  

//设置网关

 1 int SetGateWay(const char *szGateWay)  
 2 {  
 3     int ret = 0;      
 4     char cmd[128];  
 5     QString DefGW = GetGateWay();  
 6   
 7     const char *strGW = DefGW.latin1();   
 8       
 9     strcpy(cmd, "route del default gw ");  
10     strcat(cmd, strGW);  
11     ret = system(cmd);  
12     if(ret < 0)  
13     {  
14         perror("route error");  
15         return -1;  
16     }  
17     strcpy(cmd, "route add default gw ");  
18     strcat(cmd, szGateWay);  
19       
20     ret = system(cmd);  
21     if(ret < 0)  
22     {  
23         perror("route error");  
24         return -1;  
25     }  
26   
27     return ret;  
28 }  

 

 

Linux下哪些收获网卡音信  

奇迹,写程序的时候要求拿到统计机的网络新闻,比如IP地址、电脑名称、DNS等音信。IP地址和处理器名称是相比易于取得到的,而要想获得地址掩码、DNS、网关等消息就有些麻烦了。

在Windows下大家一般都是经过从注册表读取那几个信息。在Linux怎么办啊?其实,Linux下愈加便于一些。因为我们可以拿现成的次第看它的源代码。通过翻阅其源代码找到解决该问题的章程。那么,看哪个程序的源代码呢?即使你利用过Linux,并且相比熟识的话就决然晓得一个指令ifconfig。那些命令和Windows下的ipconfig大致,都可以出口网卡的新闻,其中就富含DNS、掩码等新闻。所以,大家可以通过看它的源代码来找到解决该问题的点子。

获得系统中的网卡数量

并没有那个系统调用提供网卡数量的获取。但是,我们可以通过强大的proc文件系统获取网卡数量的信息。实际上,ifconfig也是这样做的,请看示例代码如下: 

0001 #include <stdio.h>
0002 #include <string.h>
0003 #include <errno.h>
0004 
0005 int GetNetCardCount()
0006 {
0007     int nCount = 0;
0008     FILE* f = fopen("/proc/net/dev", "r");
0009     if (!f)
0010     {
0011         fprintf(stderr, "Open /proc/net/dev failed!errno:%d\n", errno);
0012         return nCount;
0013     }
0014 
0015     char szLine[512];
0016 
0017     fgets(szLine, sizeof(szLine), f);    /* eat line */
0018     fgets(szLine, sizeof(szLine), f);
0019 
0020     while(fgets(szLine, sizeof(szLine), f))
0021     {
0022         char szName[128] = {0};
0023         sscanf(szLine, "%s", szName);
0024         int nLen = strlen(szName);
0025         if (nLen <= 0)continue;
0026         if (szName[nLen - 1] == ':') szName[nLen - 1] = 0;
0027         if (strcmp(szName, "lo") == 0)continue;
0028         nCount++;
0029     }
0030 
0031     fclose(f);
0032     f = NULL;
0033     return nCount;
0034 }
0035 
0036 int main(int argc, char* argv[])
0037 {
0038     printf("NetCardCount: %d\n", GetNetCardCount());
0039     return 0;
0040 }

 

获取IP、掩码、MAC及网关

获取IP、掩码、MAC和播音地址是比较便于的,只须求调用对应的IOCTL即可。只是我们对Linux下的IOCTL可能不太谙习。却看示例代码:

 

0001 void DispNetInfo(const char* szDevName)
0002 {
0003     int s = socket(AF_INET, SOCK_DGRAM, 0);
0004     if (s < 0)
0005     {
0006         fprintf(stderr, "Create socket failed!errno=%d", errno);
0007         return;
0008     }
0009 
0010     struct ifreq ifr;
0011     unsigned char mac[6];
0012     unsigned long nIP, nNetmask, nBroadIP;
0013 
0014     printf("%s:\n", szDevName);
0015 
0016     strcpy(ifr.ifr_name, szDevName);
0017     if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0)
0018     {
0019         return;
0020     }
0021     memcpy(mac, ifr.ifr_hwaddr.sa_data, sizeof(mac));
0022     printf("\tMAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
0023             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
0024 
0025     strcpy(ifr.ifr_name, szDevName);
0026     if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
0027     {
0028         nIP = 0;
0029     }
0030     else
0031     {
0032         nIP = *(unsigned long*)&ifr.ifr_broadaddr.sa_data[2];
0033     }
0034     printf("\tIP: %s\n", inet_ntoa(*(in_addr*)&nIP));
0035 
0036     strcpy(ifr.ifr_name, szDevName);
0037     if (ioctl(s, SIOCGIFBRDADDR, &ifr) < 0)
0038     {
0039         nBroadIP = 0;
0040     }
0041     else
0042     {
0043         nBroadIP = *(unsigned long*)&ifr.ifr_broadaddr.sa_data[2];
0044     }
0045     printf("\tBroadIP: %s\n", inet_ntoa(*(in_addr*)&nBroadIP));
0046 
0047     strcpy(ifr.ifr_name, szDevName);
0048     if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0)
0049     {
0050         nNetmask = 0;
0051     }
0052     else
0053     {
0054         nNetmask = *(unsigned long*)&ifr.ifr_netmask.sa_data[2];
0055     }
0056     printf("\tNetmask: %s\n", inet_ntoa(*(in_addr*)&nNetmask));
0057     close(s);
0058 }

 

       那么什么样收获网关地址呢?越发简单,不过,好像很少有人明白。反正我在网上没有找到有人知道。最终看了nslookup的源代码将来才清楚正确的做法。代码如下:

      

 1  res_init();      
 2 
 3        for (int i = 0; i < _res.nscount; i++)
 4 
 5        {
 6 
 7               struct sockaddr* server = (struct sockaddr*)&_res.nsaddr_list[i];
 8 
 9               printf("Server:  %s\n", inet_ntoa(*(in_addr*)&(server->sa_data[2])));
10 
11        }

 

代码很粗略,就不做解释了。

 

怎么获取网关呢?那么些有点有点麻烦一些,但是和得到网卡数量相似,都是透过proc文件系统。本次分析的/proc/net/route文件。我就不再贴出示例代码了。

末段,我把运行示例程序获取到的音信附上,以供大家有个直观的认识:

eth0:

       MAC: 08-00-27-98-bf-f3

       IP: 192.168.1.106

       BroadIP: 255.255.255.255

       Netmask: 255.255.255.0

Gateway: 192.168.1.1

eth1:

       MAC: 08-00-27-16-f4-bf

       IP: 192.168.1.108

       BroadIP: 192.168.1.255

       Netmask: 255.255.255.0

Gateway: 0.0.0.0

eth2:

       MAC: 08-00-27-37-9c-91

       IP: 0.0.0.0

       BroadIP: 0.0.0.0

       Netmask: 0.0.0.0

Gateway: 0.0.0.0

eth3:

       MAC: 08-00-27-5a-d2-39

       IP: 0.0.0.0

       BroadIP: 0.0.0.0

       Netmask: 0.0.0.0

Gateway: 0.0.0.0

NetCardCount: 4

DNS 0:  218.2.135.1

DNS 1:  61.147.37.1

 

Linux下C语言配置网络与收获网络布局音讯的点子

Linux下的网络配置包含三个要素,分别是IP地址、子网掩码和网关。本文将介绍如何在C语言中进行网络的配置和配置信息的获取。





【配置】





方法一





使用system()或exec*()调用ifconfig和route命令进行配置。这种方法的优点是使用简单,缺点是效率比较低,且依赖于ifconfig与route命令。



示例:

见所附代码中的函数ip_config_system()和ip_config_exec()。





方法二





建立一个socket,用ioctl()进行配置。这种方法的优点是效率较高,缺点是程序实现起来比较麻烦。



示例:

见所附代码中的函数ip_config_ioctl()。





【获取】





方法一





用popen()建立一个管道,管道的一端执行命令ifconfig和route,管道的另一端读取收到的数据并进行相应的解析。这种方法的优点是使用简单,缺点是效率比较低,且依赖于ifconfig与route命令。



示例:

见所附代码中的函数ip_get_pipe()。





方法二





用fopen()打开/proc/net/route,可以获取网关(在/proc/net中尚未发现比较好的获取IP地址和掩码的方法,知道的请发邮件至cugfeng at gamil.com,谢谢)。这种方法的优点是使用简单,效率比执行命令高,缺点是依赖于proc文件系统。



示例:

见所附代码中的函数ip_get_proc()。





方法三





建立一个socket,用ioctl()进行获取(用ioctl()尚未发现比较好的获取网关的方法,知道的请发邮件至cugfeng at gamil.com,谢谢)。这种方法的优点是效率较高,缺点是程序实现起来比较麻烦。



示例:

见所附代码中的函数ip_get_ioctl()。





BTW,用ioctl()的方法还可以获取MAC地址,ioctl()命令为SIOCGIFHWADDR,具体用法与ioctl()获取IP地址的方法相同,这里就不多说了。

相关文章