首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言獲取公網IP地址的實現方法

     編輯:關於C

在網絡編程中,獲取本機的公網IP地址是一個常見需求。本文介紹如何使用C語言配合Windows網絡API,通過訪問外部服務來獲取公網IP地址。

核心實現思路

由於本機通常位於NAT或路由器後方,無法直接從網卡獲取公網IP。解決方案是向提供IP查詢服務的網站發送HTTP請求,解析返回的HTML頁面提取IP地址。本示例使用ip138.com作為查詢服務。

完整代碼實現

[cpp]
#include "stdafx.h"
BOOL GetPubIp(char *ip);
int main()
{
    char myip[32]={0};
    GetPubIp(myip);
    cout<<myip<<endl;
    return 0;
}
BOOL GetPubIp(char *ip)
{
    HINTERNET hInternet=NULL;
    HINTERNET hConnect=NULL;
    char szText[512]={0};
    char *szAccept="Accept: */*\r\n\r\n";
    char *szUrl="https://www.ip138.com/ip2city.asp";
    DWORD dwReadLen=0;
    __try
    {
        hInternet=InternetOpen("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",0,NULL,NULL,0);
        if(!hInternet)
            __leave;
        hConnect=InternetOpenUrl(hInternet,szUrl,szAccept,strlen(szAccept),INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_PRAGMA_NOCACHE|INTERNET_FLAG_RELOAD,0);
        if(!hConnect)
            __leave;
        InternetReadFile(hConnect,szText,512,&dwReadLen);
    }
    __finally
    {
        if(hInternet)
            InternetCloseHandle(hInternet);
        if(hConnect)
            InternetCloseHandle(hConnect);
    }
    char *start=strstr(szText,"您的IP地址是:[");
    if(!start)
        return FALSE;
    start=start+15;
    char *temp=strstr(start,"]");
    strncpy(ip,start,temp-start);
    return TRUE;
}

關鍵技術點解析

1. WinINet API的使用

代碼使用了Windows提供的WinINet API(InternetOpen、InternetOpenUrl、InternetReadFile、InternetCloseHandle)進行HTTP通信。這組API封裝了Socket層細節,適合簡單的HTTP客戶端開發。

2. 異常安全的資源管理

使用__try/__finally結構確保網絡句柄在任何情況下都能正確關閉,防止資源洩漏。這在網絡編程中尤為重要,因為連接失敗、超時等異常情況頻繁發生。

3. 響應解析策略

通過strstr查找特定標記「您的IP地址是:[」和「]」,提取中間的IP字符串。這種基於特徵字符串的解析方式簡單直接,但依賴目標網站頁面結構穩定。

注意事項與改進方向

  • 依賴外部服務:ip138.com若變更頁面結構或停止服務,代碼將失效。生產環境建議部署自有查詢服務或使用多個備選源
  • 編碼問題:返回頁面可能使用GB2312編碼,中文環境下直接處理通常無問題,跨平台時需注意編碼轉換
  • 超時控制:當前代碼無顯式超時設置,網絡不通時可能長時間阻塞
  • HTTPS支持:現代網站多遷移至HTTPS,WinINet支持HTTPS但需額外配置證書驗證

跨平台替代方案

Linux/Unix系統下可使用libcurl庫實現相同功能,代碼更簡潔且支持HTTPS、超時控制、重定向等高級特性。C++17以降可考慮使用std::experimental::net或第三方網絡庫(如Boost.Beast、cpp-httplib)。

本示例展示了Windows平台下最基礎的HTTP GET請求與響應解析流程,適合理解網絡編程基本原理,生產環境建議使用更健壯的網絡庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved