如何从C程序输出主机的IP地址?

我需要使用C语言显示来自本地计算机的所有IP地址。 如何才能做到这一点?

 #include <stdio.h> #include <stropts.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <linux/netdevice.h> #include <arpa/inet.h> #include <netinet/in.h> #include <unistd.h> int print_addresses(const int domain) { int s; struct ifconf ifconf; struct ifreq ifr[50]; int ifs; int i; s = socket(domain, SOCK_STREAM, 0); if (s < 0) { perror("socket"); return 0; } ifconf.ifc_buf = (char *) ifr; ifconf.ifc_len = sizeof ifr; if (ioctl(s, SIOCGIFCONF, &ifconf) == -1) { perror("ioctl"); return 0; } ifs = ifconf.ifc_len / sizeof(ifr[0]); printf("interfaces = %d:\n", ifs); for (i = 0; i < ifs; i++) { char ip[INET_ADDRSTRLEN]; struct sockaddr_in *s_in = (struct sockaddr_in *) &ifr[i].ifr_addr; if (!inet_ntop(domain, &s_in->sin_addr, ip, sizeof(ip))) { perror("inet_ntop"); return 0; } printf("%s - %s\n", ifr[i].ifr_name, ip); } close(s); return 1; } int main(int argc, char *argv[]) { int domains[] = { AF_INET, AF_INET6 }; int i; for (i = 0; i < sizeof(domains) / sizeof(domains[0]); i++) if (!print_addresses(domains[i])) return 1; return 0; } 

你的问题可能是不准确的,但我不知道为什么每个人都打破了你的印章。

我想你是在问你基本上可能需要的是getifaddrs 。 手册页有一个小例子程序。

您也可以使用SIOCGIFCONF选项与ioctl()获得类似的信息。 这里和网络上有一些示例代码。

如果你四处搜索这些和类似的术语,你会发现这个问题已经以各种形式被问及。 你必须挖掘一下。

另外请注意,如果你在NAT后面,这些将不会给你面向公众的IP。

用C做的另一种方法我不得不说,有很多方法可以从shell中完成,有什么意义呢?

 #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <net/if.h> #include <errno.h> #include <ifaddrs.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> void show_address_info( struct ifaddrs *ifa ){ struct sockaddr_in *s4; struct sockaddr_in6 *s6; /* ipv6 addresses have to fit in this buffer */ char buf[64]; if (AF_INET == ifa->ifa_addr->sa_family){ s4 = (struct sockaddr_in *)(ifa->ifa_addr); if (NULL == inet_ntop(ifa->ifa_addr->sa_family, (void *)&(s4->sin_addr), buf, sizeof(buf))){ printf("%s: inet_ntop failed!\n", ifa->ifa_name); } else { printf("IPv4 addr %s: %s\n", ifa->ifa_name, buf); } } else if (AF_INET6 == ifa->ifa_addr->sa_family) { s6 = (struct sockaddr_in6 *)(ifa->ifa_addr); if (NULL == inet_ntop(ifa->ifa_addr->sa_family, (void *)&(s6->sin6_addr), buf, sizeof(buf))) { printf("%s: inet_ntop failed!\n", ifa->ifa_name); } else { printf("IPv6 addr %s: %s\n", ifa->ifa_name, buf); } } } int main(int argc, char **argv){ struct ifaddrs *myaddrs, *ifa; int status; status = getifaddrs(&myaddrs); if (status != 0){ perror("getifaddrs failed!"); exit(1); } for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next){ if (NULL == ifa->ifa_addr){ continue; } if ((ifa->ifa_flags & IFF_UP) == 0) { continue; } show_address_info(ifa); } freeifaddrs(myaddrs); return 0; } 

你怎么欺骗,看看/sbin/ifconfig/的来源? 站在其他巨人的肩膀上没有错

还没有一个完整的解决方案,但看看/proc/net

  • dev按名称列出可用的接口设备,
  • route列出了一些路由,就像ipv6_route
  • arp列出实际路由表中的设备(不包括localhost)。

不像其他解决方案那样高科技,但可以通过简单的文件阅读来完成。 虽然Linux是特定的。

你需要POSIX函数getaddrinfo() – 它返回所有IP地址的链表。

有关详细信息和示例,请参阅man getaddrinfo

 $ sudo ifconfig |  grep'inet addr'|  cut -d':'-f2 | 砍掉-d''-f1
 213.xx.xxx.xx
 192.168.xx.x
 127.0.0.1

你可以把它放到popen()中 :

 /* not tested */ ph = popen("sudo ifconfig | grep 'inet addr' | cut -d':' -f2 | cut -d' ' -f1", "r"); while (fgets(buf, sizeof buf, ph)) { /* ip address, in nul-terminated string format, is in `buf` */ } pclose(ph); 
 #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> /* * Who sez? * http://blog.stackoverflow.com/2010/01/stack-overflow-where-we-hate-fun/ */ int main(int argc, char *argv[]) { int status; const char * const cmd = /* die from END is too chatty */ "/sbin/ifconfig -a | \ perl -lne \ 'print $1 if /inet6? addr:\\s*(\\S+)/; \ END { $. > 0 or \ warn(\"no output from ifconfig\\n\"), \ exit 1; }'"; status = system(cmd); if (status < 0) { perror("system"); return 1; } else if (status != 0) { const char *extra; status = WEXITSTATUS(status); extra = status == 127 ? " (is /bin/sh ok?)" : ""; fprintf(stderr, "%s: command failed with status %d%s\n", argv[0], status, extra); } return 0; }