近日偶要做个程序,需要获得外网IP,偶去网上找相关资料,发现都不尽如人意,有的
只能获得本地网卡的IP,有的通过httpget控件获取IP,还有甚者做个asp再调用偶是个
懒人,而且上面提到的方法,不是获取不了就是速度太慢或者是太麻烦,无意中发现
有个系统提供的API,利用它能够获取适配器信息,其中就包括外网IP,下面把代码给
大家,重点处我做了注释。

注意: 程序必须运行在直接拨号联网的用户,不适用于内网用户。
//常量定义
Const
MAX_HOSTNAME_LEN               = 128;
MAX_DOMAIN_NAME_LEN            = 128;
MAX_SCOPE_ID_LEN               = 256;
MAX_ADAPTER_NAME_LENGTH        = 256;
MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
MAX_ADAPTER_ADDRESS_LENGTH     = 8;
//定义相关结构
Type
TIPAddressString = Array[0..4*4-1] of Char;

PIPAddrString = ^TIPAddrString;
TIPAddrString = Record
    Next      : PIPAddrString;
    IPAddress : TIPAddressString;
    IPMask    : TIPAddressString;
    Context   : Integer;
End;

PFixedInfo = ^TFixedInfo;
TFixedInfo = Record { FIXED_INFO }
    HostName         : Array[0..MAX_HOSTNAME_LEN+3] of Char;
    DomainName       : Array[0..MAX_DOMAIN_NAME_LEN+3] of Char;
    CurrentDNSServer : PIPAddrString;
    DNSServerList    : TIPAddrString;
    NodeType         : Integer;
    ScopeId          : Array[0..MAX_SCOPE_ID_LEN+3] of Char;
    EnableRouting    : Integer;
    EnableProxy      : Integer;
    EnableDNS        : Integer;
End;

PIPAdapterInfo = ^TIPAdapterInfo;
TIPAdapterInfo = Record { IP_ADAPTER_INFO }
    Next                : PIPAdapterInfo;
    ComboIndex          : Integer;
    AdapterName         : Array[0..MAX_ADAPTER_NAME_LENGTH+3] of Char;
    Description         : Array[0..MAX_ADAPTER_DESCRIPTION_LENGTH+3] of Char;
    AddressLength       : Integer;
    Address             : Array[1..MAX_ADAPTER_ADDRESS_LENGTH] of Byte;
    Index               : Integer;
    _Type               : Integer;
    DHCPEnabled         : Integer;
    CurrentIPAddress    : PIPAddrString;
    IPAddressList       : TIPAddrString;
    GatewayList         : TIPAddrString;
    DHCPServer          : TIPAddrString;
    HaveWINS            : Bool;
    PrimaryWINSServer   : TIPAddrString;
    SecondaryWINSServer : TIPAddrString;
    LeaseObtained       : Integer;
    LeaseExpires        : Integer;
End;
type
TGetAdaptersInfo=function(AI : PIPAdapterInfo; Var BufLen : Integer) : Integer;StdCall;
var
GetAdaptersInfo:TGetAdaptersInfo;
h:hmodule;

implementation

function Loadiphlpapidll:boolean;//动态加载iphlpapi.dll中的GetAdaptersInfo
begin
if h>0 then exit;
h:=Loadlibrary('iphlpapi.dll');
if h>0 then
   GetAdaptersInfo:=GetProcAddress(h,'GetAdaptersInfo');
result:=assigned(GetAdaptersInfo);
end;
function GetWanIP: string;//获取外网IP
Var
AI,Work : PIPAdapterInfo;
Size    : Integer;
Res     : Integer;
Description:string;
WanIP:string;
Function GetAddrString(Addr : PIPAddrString) : String;
Begin
    Result := '';
    While (Addr <> nil) do Begin
      Result := Result+'A: '+Addr^.IPAddress+' M: '+Addr^.IPMask+#13;
      Addr := Addr^.Next;
    End;
End;
begin
Loadiphlpapidll;
result:='无法获得外网IP';
Size := 5120;
GetMem(AI,Size);
Res := GetAdaptersInfo(AI,Size);
If (Res <> ERROR_SUCCESS) Then
Begin
   MessageBoxA(0,'获取外网IP失败    ','错误',MB_OK or MB_ICONERROR);
   exit;
End;
    Work := AI;
    Repeat
       Description:=strpas(Work^.Description);
       if pos('WAN',Description)>0 then
        begin
         WanIP:=GetAddrString(@Work^.IPAddressList);
         //这里返回的WanIP是这种格式 A: 222.111.25.32 M: 255.255.255.0
         //其中A到M中间就是外网IP了
         WanIP:=copy(WanIP,pos(':',WanIP)+1,pos('M',WanIP)-pos(':',WanIP)-2);
         result:=trim(WanIP);//这里就是最终的外网IP了
         exit;
        end;
      Work := Work^.Next;
    Until (Work = nil);
FreeMem(AI);

end;

http://blog.csdn.net/yanjiaye520/article/details/7702409

Delphi 取外网IP的更多相关文章

  1. linux下获取外网IP

    使用阿里云或者有多个网卡IP的机器需要取外网IP时,可以用下面这种 wget -qO - ifconfig.co 更多方法参考:https://yq.aliyun.com/ziliao/105999

  2. Visual Studio 2017 - Windows应用程序打包成exe文件(2)- Advanced Installer 关于Newtonsoft.Json,LINQ to JSON的一个小demo mysql循环插入数据、生成随机数及CONCAT函数 .NET记录-获取外网IP以及判断该IP是属于网通还是电信 Guid的生成和数据修整(去除空格和小写字符)

    Visual Studio 2017 - Windows应用程序打包成exe文件(2)- Advanced Installer   Advanced Installer :Free for 30 da ...

  3. java web获取客户端外网ip和所在区域

    @参考文章1.@参考文章2.@参考文章3.@参考文章4,@之前同事的项目 controller @Controller @RequestMapping("/home") publi ...

  4. 查看linux系统外网ip命令

    终端中输入 curl ipinfo.io 或者 curl ifconfig.me 即可通过IP地址检测网站提供的api获得取本机的外网IP,或者以 JSON 格式返回全部结果.

  5. C#获取本机内网外网IP

    using System.Net; # region 获取内.外网Ip /// <summary> /// 获取本地ip地址,优先取内网ip /// </summary> pu ...

  6. nginx反向代理下thinkphp、php获取不到正确的外网ip

    在记录用户发送短信需要获取用户ip时,tp一直获取的是内网ip:10.10.10.10 tp框架获取ip方法:get_client_ip /** * 获取客户端IP地址 * @param intege ...

  7. c#获取外网IP地址的方法

    1.如果你是通过路由上网的,可以通过访问ip138之类的地址来获取外网IP 2.如果是通过PPPOE拨号上网的,可以使用以下代码获取IP //获取宽带连接(PPPOE拨号)的IP地址,timeout超 ...

  8. 读取本地外网IP地址

    读取本地外网IP地址. 根据启动并运行的网卡名称,找到本机实际的IP地址(已知当前运行的无线网卡名包含某一个字符) import java.net.InterfaceAddress; import j ...

  9. 爬虫, 获取登录者的外网IP

    笔者学习了一下用爬虫, 获取登录者的外网IP. 首先导入Jsoup的jar包 public class RetrivePage { private static String url="ht ...

随机推荐

  1. ORACLE触发器和new、old特殊变量

    :new --为一个引用最新的列值;:old --为一个引用以前的列值; 这两个变量只有在使用了关键字 "FOR EACH ROW"时才存在.且update语句两个都有,而inse ...

  2. php number_format()保留小数点后几位有效数的函数 千位分组来格式化数字(转)

    PHP保留小数点后2位的函数number_format number_format(带小数点的书,小数点后保留的位数) number_format(8.3486,2);  //取得小数点后2位有效数/ ...

  3. Counting Triangles(hd1396)

    Counting Triangles Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. c语言函数注意点

    返回值的基本概念.return的作用    return 1>void可以省略return 2>可以多次使用return 3>return后面不能有其他语句   4. 函数的弱语法 ...

  5. TensorFlow 深度学习笔记 从线性分类器到深度神经网络

    转载请注明作者:梦里风林 Github工程地址:https://github.com/ahangchen/GDLnotes 欢迎star,有问题可以到Issue区讨论 官方教程地址 视频/字幕下载 L ...

  6. Oracle EBS-SQL (CST-3):检查零成本交易.sql

    SELECT            '零成本交易'                                交易异常类型          ,msi.segment1               ...

  7. android的edittext输入长度

    http://blog.csdn.net/uyu2yiyi/article/details/6329738 http://flysnow.iteye.com/blog/828415/ http://s ...

  8. android透明度和css透明度

    值越小,越透明 css:0.1-------1 android:#00-----------#ff

  9. 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记

    A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Descr ...

  10. 匿名方法和Lambda表达式

    匿名方法本质上是一传递给委托的代码块,是使用委托的另一种方法. 规则: 1.匿名方法中不能使用跳转语句跳至次匿名方法的外部,反之亦然:匿名方法外部的跳转语句也不能跳转到匿名方法的内部: 2.在匿名方法 ...