在Linux下获得本机的IP地址,有以下几种方法,现终结如下:其中主要用到的,数据结构有以下几个。
struct ifreq 其定义在 /usr/include/net/if.h中。主要用来配置ip,激活接口信息。通常会和ifconf结合起来使用。这里有篇介绍这两个数据结构比较好的文章,链接如下:
网上有介绍可以使用gethostname函数和gethostbyname函数获得本机的IP地址,其实获得的是127.0.0.1,是一个回环的地址。而不是真正的本机IP地址。
struct hostent *ent;
gethostname(host_name,200);
ent = gethostbyname(host_name);
printf("****************************************\n");
printf("The local host ip address: %s\n",inet_ntoa(*(struct in_addr *)ent->h_addr));
struct ifreq
{
# define IFHWADDRLEN 6
# define IFNAMSIZ IF_NAMESIZE
union
{
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0".
这个参数是经常使用的,也就是接口的名字
通常第一个网卡的名字是 “eth0” */
} ifr_ifrn;
union
{
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short int ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ]; /* Just fits the size */
char ifru_newname[IFNAMSIZ];
__caddr_t ifru_data;
} ifr_ifru;
};
# define ifr_name ifr_ifrn.ifrn_name /* interface name */
# define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
# define ifr_addr ifr_ifru.ifru_addr /* address */
# define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
# define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
# define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
# define ifr_flags ifr_ifru.ifru_flags /* flags */
# define ifr_metric ifr_ifru.ifru_ivalue /* metric */
# define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
# define ifr_map ifr_ifru.ifru_map /* device map */
# define ifr_slave ifr_ifru.ifru_slave /* slave device */
# define ifr_data ifr_ifru.ifru_data /* for use by interface */
# define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
# define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
# define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */
# define ifr_newname ifr_ifru.ifru_newname /* New name */
# define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
# define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
# define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
|
struct ifconf
{
int ifc_len; /* Size of buffer. */
union
{
__caddr_t ifcu_buf;
struct ifreq *ifcu_req;
} ifc_ifcu;
};
# define ifc_buf ifc_ifcu.ifcu_buf /* Buffer address. */
# define ifc_req ifc_ifcu.ifcu_req /* Array of structures. */
# define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0) /* not right */
|
void GetIP(void)
{
int socket_fd;
struct sockaddr_in *sin;
struct ifreq *ifr;
struct ifconf conf;
char buff[BUFSIZ];
int num;
int i;
socket_fd = socket(AF_INET,SOCK_DGRAM,0);
conf.ifc_len = BUFSIZ;
conf.ifc_buf = buff;
ioctl(socket_fd,SIOCGIFCONF,&conf);
num = conf.ifc_len / sizeof(struct ifreq);
ifr = conf.ifc_req;
printf("num=%d\n",num);
for(i=0;i<num;i++)
{
struct sockaddr_in *sin = (struct sockaddr_in *)(&ifr->ifr_addr);
ioctl(socket_fd,SIOCGIFFLAGS,ifr);
if(((ifr->ifr_flags & IFF_LOOPBACK) == 0) && (ifr->ifr_flags & IFF_UP))
{
printf("%s(%s)\n",ifr->ifr_name,inet_ntoa(sin->sin_addr));
}
ifr++;
}
}
|
void GetIP2(void)
{
int socket_fd;
struct sockaddr_in *sin;
struct ifreq ifr;
struct ifconf conf;
char buff[BUFSIZ];
int num;
int i;
socket_fd = socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd ==-1)
{
perror("socket error!\n");
return -1;
}
strcpy(ifr.ifr_name,"eth1");
//这里要特别的注意,根据自己的系统的不同会有所差异有可能会是“eth0“。 如果出现错误提示 No such device 可能是这里的问题
if(ioctl(socket_fd,SIOCGIFADDR,&ifr) < 0)
{
perror("ioctl error\n");
return -1;
}
else
{
sin = (struct sockaddr_in *)&(ifr.ifr_addr);
printf("current IP = %s\n",inet_ntoa(sin->sin_addr));
}
}
|
还有一种IPv4和IPv6都通用的,主要参考网上的资料:#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#define ETH_NAME "eth0"
#include <linux/sockios.h>
#include <ifaddrs.h>
int GetIP_v4_and_v6_linux(int family,char *address,int size)
{
struct ifaddrs *ifap0,*ifap;
char buf[NI_MAXHOST];
char *interface = "eth1";
struct sockaddr_in *addr4;
struct sockaddr_in6 *addr6;
int ret;
if(NULL == address)
{
printf("in address");
return -1; }
if(getifaddrs(&ifap0))
{
return -1;
}
for(ifap = ifap0;ifap!=NULL;ifap=ifap->ifa_next)
{
if(strcmp(interface,ifap->ifa_name)!=0) continue;
if(ifap->ifa_addr == NULL) continue;
if((ifap->ifa_flags & IFF_UP) == 0) continue;
if(family!=ifap->ifa_addr->sa_family) continue;
if(AF_INET == ifap->ifa_addr->sa_family)
{
addr4 = (struct sockaddr_in *)ifap->ifa_addr;
if(NULL != inet_ntop(ifap->ifa_addr->sa_family,(void *)&(addr4->sin_addr),buf,NI_MAXHOST))
{
if(size <=strlen(buf)) break;
strcpy(address,buf);
printf("address %s\n",address);
freeifaddrs(ifap0);
return 0;
}
else break;
}
else if(AF_INET6 == ifap->ifa_addr->sa_family)
{
addr6 = (struct sockaddr_in6*) ifap->ifa_addr;
if(IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr))
{
continue;
}
if(IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr))
{
continue;
}
if(IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr))
{
continue;
}
if(IN6_IS_ADDR_UNSPECIFIED(&addr6->sin6_addr))
{
continue;
}
if(IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr))
{
continue;
}
if(NULL != inet_ntop(ifap->ifa_addr->sa_family,(void *)&(addr6->sin6_addr),buf,NI_MAXHOST))
{
if(size <= strlen(buf)) break;
strcpy(address,buf);
freeifaddrs(ifap0);
return 0;
}
else break;
}
}
freeifaddrs(ifap0);
return -1;
}
int main(void)
{
char ip_addr[16];
char *ip ;
ip= ip_addr;
GetIP_v4_and_v6_linux(AF_INET,ip,16);
printf("ip addrss %s\n", ip);
}
|
阅读(1963) | 评论(0) | 转发(0) |