在这里的回答中建议,获取机器的IP地址,可以使用getifaddrs()
来获取正在运行程序的机器的IP地址,效果很好:D:D
然而,在两个不同的系统上运行相同的程序,其中一个显示
SERVER_ADDRESS lo 127.0.0.1
SERVER_ADDRESS eth0 129.xxx.xxx.xxx
SERVER_ADDRESS virbr0 192.zzz.zzz.1
而另一个显示
SERVER_ADDRESS lo0 127.0.0.1
SERVER_ADDRESS en0 192.yyy.yyy.yyy
我打算使用strcmp
来区分以太网,但现在我意识到它不能跨系统工作,因为可能会打印出不同的字符串。
是否有功能(或更好的方法)来检查ifa_name
是否为以太网?
要(再次)明确地声明这一点:127.0.0.0/255.0.0.0
网(范围)的所有地址(从127.0.0.0
到127.255.255.255
)都被定义为本地环回地址。此地址的数据将不会离开本地机器。
无论如何,因为你已经使用getifaddrs()
生活很容易。-测试结构体struct ifaddrs
的成员ifa_flags
返回IFF_LOOPBACK
,像这样:
#include <sys/types.h>
#include <ifaddrs.h>
#include <net/if.h> /* for IFF_LOOPBACK */
...
struct ifaddrs * pIfAddrs = NULL;
if (!getifaddrs(&pIfAddrs)) {
/* Test if the first interface is looping back to the local host. */
int iIsLoopBack = (0 != (pIfAddrs->ifa_flags & IFF_LOOPBACK));
...
}
...
/* clean up */
if (pIfAddrs) {
freeifaddrs(pIfAddrs);
pIfAddrs = NULL;
}
...
你可能会遇到更多的问题。例如,有多个nic、vlan、wan看起来像lan,反之亦然,等等。
什么是已知的?127.X.X.X
去掉这个结果,你就得到了你的非循环。
如果你想知道地址是否私有…然后你就得沿着这条路走下去。
/* Output:
Name: 'eth0' Addr: 'xxx.xxx.xxx.xxx'
Name: 'eth0:0' Addr: 'xxx.xxx.xxx.xxx'
*/
struct ifaddrs *ifaddr;
char ip[255];
if (getifaddrs(&ifaddr) == -1)
{
//sprintf(ip[0], "%s", strerror(errno));
}
else
{
struct ifaddrs *ifa;
int i = 0, family;
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == NULL)
{
continue;
}
family = ifa->ifa_addr->sa_family;
if (family == AF_INET || family == AF_INET6)
{
if(!(ifa->ifa_flags & IFF_LOOPBACK) && (family == AF_INET) && getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), ip, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0)
{
printf("Name: '%s' Addr: '%s'n", ifa->ifa_name, ip);
}
}
}
}
freeifaddrs(ifaddr);