21xrx.com
2025-04-05 19:54:29 Saturday
文章检索 我的文章 写文章
Linux C++如何获取本机IP地址
2023-07-02 03:38:05 深夜i     12     0
Linux C++ 获取 本机IP地址

在Linux C++中,获取本机的IP地址是一个常见的需求。本文将介绍如何使用C++语言获取本机IP地址的方法。

Linux中获取IP地址的方法一般有两种,分别是使用系统调用和使用Socket编程接口。

使用系统调用

系统调用是向操作系统请求某种服务或功能的接口,在Linux中,获取本机IP地址也可以通过调用系统函数来实现。

实现方法如下:

1. 引入相关的头文件

#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>

2. 定义一个结构体存储获取到的IP地址

struct ifaddrs {
  struct ifaddrs *ifa_next;
  char *ifa_name;
  unsigned int ifa_flags;
  struct sockaddr *ifa_addr;
  struct sockaddr *ifa_netmask;
  ...
};

其中,ifa_name表示网卡的名字,ifa_flags表示网卡的状态,ifa_addr表示网卡的IP地址,ifa_netmask表示网卡的子网掩码等。

3. 获取本机所有网卡的信息

struct ifaddrs *ifAddrStruct = NULL;
if (getifaddrs(&ifAddrStruct) == -1) {
  printf("getifaddrs error!");
}

通过系统函数getifaddrs获取本机的所有网卡信息,如果出错则会返回-1。

4. 遍历所有网卡,查找有效的IP地址

while (ifAddrStruct) {
  if (ifAddrStruct->ifa_addr->sa_family == AF_INET) {//IPv4地址
    char *ip = inet_ntoa(((struct sockaddr_in *) ifAddrStruct->ifa_addr)->sin_addr);
    printf("interface: %s, IPv4 address: %s\n", ifAddrStruct->ifa_name, ip);
    break;
  } else if (ifAddrStruct->ifa_addr->sa_family == AF_INET6) {//IPv6地址
    struct sockaddr_in6 *addr = (struct sockaddr_in6 *) ifAddrStruct->ifa_addr;
    char str[INET6_ADDRSTRLEN];
    inet_ntop(AF_INET6, &(addr->sin6_addr), str, INET6_ADDRSTRLEN);
    printf("interface: %s, IPv6 address: %s\n", ifAddrStruct->ifa_name, str);
  }
  ifAddrStruct = ifAddrStruct->ifa_next;
}

遍历所有网卡的信息,如果是IPv4地址,则调用inet_ntoa函数将IP地址转换成字符串形式并打印输出;如果是IPv6地址,则使用inet_ntop函数进行转换并输出。

完整代码如下:

#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
int main() {
  struct ifaddrs *ifAddrStruct = NULL;
  if (getifaddrs(&ifAddrStruct) == -1) {
    printf("getifaddrs error!");
  }
  while (ifAddrStruct) {
    if (ifAddrStruct->ifa_addr->sa_family == AF_INET) {
      char *ip = inet_ntoa(((struct sockaddr_in *) ifAddrStruct->ifa_addr)->sin_addr);
      printf("interface: %s, IPv4 address: %s\n", ifAddrStruct->ifa_name, ip);
      break;
    } else if (ifAddrStruct->ifa_addr->sa_family == AF_INET6) {
      struct sockaddr_in6 *addr = (struct sockaddr_in6 *) ifAddrStruct->ifa_addr;
      char str[INET6_ADDRSTRLEN];
      inet_ntop(AF_INET6, &(addr->sin6_addr), str, INET6_ADDRSTRLEN);
      printf("interface: %s, IPv6 address: %s\n", ifAddrStruct->ifa_name, str);
    }
    ifAddrStruct = ifAddrStruct->ifa_next;
  }
  freeifaddrs(ifAddrStruct);
  return 0;
}

使用Socket编程接口

另外一种获取本机IP地址的方法是使用Socket编程接口,这种方法调用了socket函数和getsockname函数。

实现方法如下:

1. 引入相关的头文件

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

2. 创建Socket

int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == -1) {
  printf("create socket error!");
}

调用系统函数socket创建一个Socket。

3. 绑定Socket

struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(80);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
  printf("bind error!");
}

将Socket绑定到一个本地地址,这里使用INADDR_ANY表示任意主机地址。

4. 获取本地Socket的信息

struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
socklen_t addrlen = sizeof(addr);
if (getsockname(sock, (struct sockaddr *)&addr, &addrlen) == -1) {
  printf("getsockname error!");
}
close(sock);
char *ip = inet_ntoa(addr.sin_addr);
printf("local IP address: %s\n", ip);

调用系统函数getsockname获取Socket绑定的本地地址信息,在获取到信息后就可以关闭Socket了。最后使用inet_ntoa函数将IP地址转换成字符串并输出。

完整代码如下:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
int main() {
  int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sock == -1) {
    printf("create socket error!");
  }
  struct sockaddr_in sin;
  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;
  sin.sin_port = htons(80);
  sin.sin_addr.s_addr = htonl(INADDR_ANY);
  if (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
    printf("bind error!");
  }
  struct sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));
  socklen_t addrlen = sizeof(addr);
  if (getsockname(sock, (struct sockaddr *)&addr, &addrlen) == -1) {
    printf("getsockname error!");
  }
  close(sock);
  char *ip = inet_ntoa(addr.sin_addr);
  printf("local IP address: %s\n", ip);
  return 0;
}

总结

获取本机IP地址是系统编程中的基本要求,本文介绍了两种常用方法,一种是使用系统调用,另一种是使用Socket编程接口。在实际开发中,可以根据具体需求选择合适的方法。

  
  

评论区

请求出错了