如何获取本地计算机的 IP 地址?

新手上路,请多包涵

在 C++ 中,获取本地计算机的 IP 地址和子网掩码的最简单方法是什么?

我希望能够在我的本地网络中检测到本地机器的 IP 地址。在我的特殊情况下,我有一个子网掩码为 255.255.255.0 的网络,我的计算机的 IP 地址是 192.168.0.5。我需要以编程方式获取这些有两个值,以便向我的网络发送广播消息(对于我的特殊情况,格式为 192.168.0.255)

编辑:许多答案没有给出我预期的结果,因为我有两个不同的网络 IP。 Torial 的代码成功了(它给了我两个 IP 地址)。

编辑 2:感谢 Brian R. Bondy 提供有关子网掩码的信息。

原文由 djeidot 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
1 个回答

此答案 的修改版本。

添加了头文件和库。

它也基于这些页面:

获取适配器地址

IP_ADAPTER_ADDRESSES_LH

IP_ADAPTER_UNICAST_ADDRESS_LH

简而言之,要获得 IPv4 地址,您调用 GetAdaptersAddresses() 来获得适配器,然后运行 IP_ADAPTER_UNICAST_ADDRESS 结构以 FirstUnicastAddress Address 并获得 --- 字段,然后使用 inet_ntop() 将其转换为可读格式。

以以下格式打印信息:

 [ADAPTER]: Realtek PCIe
[NAME]:    Ethernet 3
[IP]:      123.123.123.123

可以编译:

 cl test.cpp

或者,如果您需要在命令行中添加 libs 依赖项:

 cl test.cpp Iphlpapi.lib ws2_32.lib

 #include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <ws2tcpip.h>

// Link with Iphlpapi.lib and ws2_32.lib
#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

void ListIpAddresses() {
  IP_ADAPTER_ADDRESSES* adapter_addresses(NULL);
  IP_ADAPTER_ADDRESSES* adapter(NULL);

  DWORD adapter_addresses_buffer_size = 16 * 1024;

  // Get adapter addresses
  for (int attempts = 0; attempts != 3; ++attempts) {
    adapter_addresses = (IP_ADAPTER_ADDRESSES*) malloc(adapter_addresses_buffer_size);

    DWORD error = ::GetAdaptersAddresses(AF_UNSPEC,
      GAA_FLAG_SKIP_ANYCAST |
        GAA_FLAG_SKIP_MULTICAST |
        GAA_FLAG_SKIP_DNS_SERVER |
        GAA_FLAG_SKIP_FRIENDLY_NAME,
      NULL,
      adapter_addresses,
      &adapter_addresses_buffer_size);

    if (ERROR_SUCCESS == error) {
      break;
    }
    else if (ERROR_BUFFER_OVERFLOW == error) {
      // Try again with the new size
      free(adapter_addresses);
      adapter_addresses = NULL;
      continue;
    }
    else {
      // Unexpected error code - log and throw
      free(adapter_addresses);
      adapter_addresses = NULL;
      return;
    }
  }

  // Iterate through all of the adapters
  for (adapter = adapter_addresses; NULL != adapter; adapter = adapter->Next) {
    // Skip loopback adapters
    if (IF_TYPE_SOFTWARE_LOOPBACK == adapter->IfType) continue;

    printf("[ADAPTER]: %S\n", adapter->Description);
    printf("[NAME]:    %S\n", adapter->FriendlyName);

    // Parse all IPv4 addresses
    for (IP_ADAPTER_UNICAST_ADDRESS* address = adapter->FirstUnicastAddress; NULL != address; address = address->Next) {
      auto family = address->Address.lpSockaddr->sa_family;
      if (AF_INET == family) {
        SOCKADDR_IN* ipv4 = reinterpret_cast<SOCKADDR_IN*>(address->Address.lpSockaddr);
        char str_buffer[16] = {0};
        inet_ntop(AF_INET, &(ipv4->sin_addr), str_buffer, 16);

        printf("[IP]:      %s\n", str_buffer);
      }
    }
    printf("\n");
  }

  free(adapter_addresses);
  adapter_addresses = NULL;
}

int main() {
  ListIpAddresses();
  return 0;
}

原文由 mortalis 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题