C++获取本地IP地址,区分VPN和本地网络

发布于 2024-11-05 18:49:02 字数 906 浏览 3 评论 0原文

我的计算机连接到 IP 地址为 10.3.3.3 的本地网络(以太网适配器),并连接到 IP 地址为 172.4.0.70 的 VPN(PPP 适配器)

现在,我如何获取我的本地 IP(10.3.3.3)以编程方式?

我已经使用以下代码进行了测试。

但我无法区分 VPN 和本地网络,任何帮助将不胜感激。

 WSAData .....;

 char* address=NULL;

 getLocalIP(&address);

 int getLocalIP(char** raddr)
 {
      char ac[80];
      if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR)
      {
            return 1;
      }

      struct hostent *phe = gethostbyname(ac);
      if (phe == 0)
      {
          return 1;
      }
      for (int i = 0; phe->h_addr_list[i] != 0; ++i)
      {
          struct in_addr addr;
          memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr));

          //How can I tell if it's not VPN?

          //if (isnotVPN){

          *raddr=inet_ntoa(addr); //<== ip address

          //break;}
      }
      return 0;
 }

由 小码哥发布于 VS2008 Win7 64位

My computer is connected to the local network(ethernet adapter) with ip address 10.3.3.3 and it is connected with my VPN(PPP adapter) with the IP address 172.4.0.70

Now, how can I get my local IP(10.3.3.3) programmatically?

I had tested using the following code.

But I can't differentiate between the VPN and local network, any help will be much appreciated.

 WSAData .....;

 char* address=NULL;

 getLocalIP(&address);

 int getLocalIP(char** raddr)
 {
      char ac[80];
      if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR)
      {
            return 1;
      }

      struct hostent *phe = gethostbyname(ac);
      if (phe == 0)
      {
          return 1;
      }
      for (int i = 0; phe->h_addr_list[i] != 0; ++i)
      {
          struct in_addr addr;
          memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr));

          //How can I tell if it's not VPN?

          //if (isnotVPN){

          *raddr=inet_ntoa(addr); //<== ip address

          //break;}
      }
      return 0;
 }

c++
VS2008
Win7 64bits

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乖不如嘢 2024-11-12 18:49:02

几年后...
刚刚遇到了同样的问题,并找到了解决方案。您可以使用 GetAdaptersInfo() 获取所有本地适配器,然后循环浏览列表并选择第一个具有有效子网掩码和默认网关的适配器(我的 VPN 适配器没有)。
如果您同时拥有带有默认网关的 WiFi 和以太网!!,我想您可以使用 Type 字段来选择以太网。

这类似于 MSDN 上的 GetAdaptersInfo() 示例代码。

PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
PIP_ADDR_STRING pIPAddrString, pIPGwString;
ULONG ulOutBufLen;

pAdapterInfo = (IP_ADAPTER_INFO *)malloc( sizeof( IP_ADAPTER_INFO ) );
if( !pAdapterInfo ); //Malloc Failed

ulOutBufLen = sizeof( IP_ADAPTER_INFO );

if( GetAdaptersInfo( pAdapterInfo, &ulOutBufLen ) == ERROR_BUFFER_OVERFLOW ) {
    free( pAdapterInfo );
    pAdapterInfo = (IP_ADAPTER_INFO *)malloc( ulOutBufLen ); 
    if( !pAdapterInfo ); //Malloc Failed 
}

if( ( dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) ) == NO_ERROR ) {
    pAdapter = pAdapterInfo;
    while( pAdapter ) {
        pIPAddrString = &pAdapter->IpAddressList;
        pIPGwString = &pAdapter->GatewayList;
        while( pIPAddrString ) {
            ULONG ulIPMask, ulIPGateway;
            ulIPMask = ntohl( inet_addr( pIPAddrString->IpMask.String ) );
            ulIPGateway = ntohl( inet_addr( pIPGwString->IpAddress.String ) );

            if( !ulIPMask ) {
                pIPAddrString = pIPAddrString->Next;
                continue;
            }

            //First adapter with a default gateway
            if ( ulIPGateway ) {
                strncpy( GETYOURSTRINGHERE, pIPAddrString->IpAddress.String, sizeof(pIPAddrString->IpAddress.String));
                free( pAdapterInfo );
                return;
            }
            pIPAddrString = pIPAddrString->Next;
        }
        pAdapter = pAdapter->Next;
    }
}

if ( pAdapterInfo )
   free( pAdapterInfo );

Few years later...
Just ran into the same issue, and figured out a solution. You can use GetAdaptersInfo() to get all the local adapters, and then cycle through the list and pick the first with a valid subnet mask and a default gateway (my VPN adapter didn't have one).
If you have both WiFi and Ethernet with default gateways!!, I guess you can use the Type field to pick Ethernet..

This is similar to the sample code for GetAdaptersInfo() on MSDN.

PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
PIP_ADDR_STRING pIPAddrString, pIPGwString;
ULONG ulOutBufLen;

pAdapterInfo = (IP_ADAPTER_INFO *)malloc( sizeof( IP_ADAPTER_INFO ) );
if( !pAdapterInfo ); //Malloc Failed

ulOutBufLen = sizeof( IP_ADAPTER_INFO );

if( GetAdaptersInfo( pAdapterInfo, &ulOutBufLen ) == ERROR_BUFFER_OVERFLOW ) {
    free( pAdapterInfo );
    pAdapterInfo = (IP_ADAPTER_INFO *)malloc( ulOutBufLen ); 
    if( !pAdapterInfo ); //Malloc Failed 
}

if( ( dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) ) == NO_ERROR ) {
    pAdapter = pAdapterInfo;
    while( pAdapter ) {
        pIPAddrString = &pAdapter->IpAddressList;
        pIPGwString = &pAdapter->GatewayList;
        while( pIPAddrString ) {
            ULONG ulIPMask, ulIPGateway;
            ulIPMask = ntohl( inet_addr( pIPAddrString->IpMask.String ) );
            ulIPGateway = ntohl( inet_addr( pIPGwString->IpAddress.String ) );

            if( !ulIPMask ) {
                pIPAddrString = pIPAddrString->Next;
                continue;
            }

            //First adapter with a default gateway
            if ( ulIPGateway ) {
                strncpy( GETYOURSTRINGHERE, pIPAddrString->IpAddress.String, sizeof(pIPAddrString->IpAddress.String));
                free( pAdapterInfo );
                return;
            }
            pIPAddrString = pIPAddrString->Next;
        }
        pAdapter = pAdapter->Next;
    }
}

if ( pAdapterInfo )
   free( pAdapterInfo );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文