21xrx.com
2024-12-22 23:59:46 Sunday
登录
文章检索 我的文章 写文章
Linux C++如何获取本机IP地址
2023-07-02 03:38:05 深夜i     --     --
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编程接口。在实际开发中,可以根据具体需求选择合适的方法。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复