DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: tino0914
今日帖子: 28
在线用户: 14
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 dalas (dalas) ★☆☆☆☆ -
普通会员
2021/9/20 22:52:49
标题:
请教用GetAdaptersAddresses获IPv4,IPv6地址 浏览:1560
加入我的收藏
楼主: 想用GetAdaptersAddresses获取IPv4,IPv6地址,下面这个把IP地址转为字符串的函数WSAAddressToString,编译不了,请大神帮忙看看:

  function SOCKET_ADDRESS_ToString(const Addr: SOCKET_ADDRESS):String;
  var
    Len: DWORD;
  begin
    Result := '';
    if (Addr.lpSockaddr <> nil) and (Addr.iSockaddrLength > 0) then
    begin
      Len := 0;
      WSAAddressToString(Addr.lpSockaddr, Addr.iSockaddrLength, nil, nil, Len); // 这行不能编译
      SetLength(Result, Len);
      if WSAAddressToString(Addr.lpSockaddr, Addr.iSockaddrLength, nil, PChar(Result), Len) = 0 then
        SetLength(Result, Len - 1)
      else
        Result := '';
    end;
  end;

调用:
引用 Winapi.WinSock2, Winapi.IpTypes, Winapi.IpHlpApi

    Flags:=GAA_FLAG_INCLUDE_PREFIX     or 
          GAA_FLAG_INCLUDE_WINS_INFO  or 
          GAA_FLAG_INCLUDE_GATEWAYS   or 
          GAA_FLAG_INCLUDE_TUNNEL_BINDINGORDER;

GetAdaptersAddresses(AF_UNSPEC, Flags, nil, pAI, @OutBufLen);

IP:=SOCKET_ADDRESS_ToString(pAI^.FirstAnycastAddress.Address);
----------------------------------------------
-
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2021/9/21 0:08:50
1楼: uses IpHlpApi, IpTypes;

procedure RetrieveLocalAdapterInformation(strings: TStrings);
var
  pAdapterInfo, pTempAdapterInfo: PIP_ADAPTER_INFO;
  AdapterInfo: IP_ADAPTER_INFO;
  BufLen: DWORD;
  Status: DWORD;
  strMAC: String;
  i: Integer;
begin
  strings.Clear;

  BufLen:= sizeof(AdapterInfo);
  pAdapterInfo:= @AdapterInfo;

  Status:= GetAdaptersInfo(nil, BufLen);
  pAdapterInfo:= AllocMem(BufLen);
  try
    Status:= GetAdaptersInfo(pAdapterInfo, BufLen);

    if (Status <> ERROR_SUCCESS) then
      begin
        case Status of
          ERROR_NOT_SUPPORTED:
          strings.Add('GetAdaptersInfo is not supported by the operating ' +
          'system running on the local computer.');
          ERROR_NO_DATA:
          strings.Add('No network adapter on the local computer.');
        else
          strings.Add('GetAdaptersInfo failed with error #' + IntToStr(Status));
        end;
        Dispose(pAdapterInfo);
        Exit;
      end;

    while (pAdapterInfo <> nil) do
      begin
        strings.Add('Description: ' + pAdapterInfo^.Description);
        strings.Add('Name: ' + pAdapterInfo^.AdapterName);

        strMAC := '';
        for I := 0 to pAdapterInfo^.AddressLength - 1 do
          strMAC := strMAC + '-' + IntToHex(pAdapterInfo^.Address[I], 2);

        Delete(strMAC, 1, 1);
        strings.Add('MAC address: ' + strMAC);
        strings.Add('IP address: ' + pAdapterInfo^.IpAddressList.IpAddress.S);
        strings.Add('IP subnet mask: ' + pAdapterInfo^.IpAddressList.IpMask.S);
        strings.Add('Gateway: ' + pAdapterInfo^.GatewayList.IpAddress.S);
        strings.Add('DHCP enabled: ' + IntTOStr(pAdapterInfo^.DhcpEnabled));
        strings.Add('DHCP: ' + pAdapterInfo^.DhcpServer.IpAddress.S);
        strings.Add('Have WINS: ' + BoolToStr(pAdapterInfo^.HaveWins,True));
        strings.Add('Primary WINS: ' + pAdapterInfo^.PrimaryWinsServer.IpAddress.S);
        strings.Add('Secondary WINS: ' + pAdapterInfo^.SecondaryWinsServer.IpAddress.S);

        pTempAdapterInfo := pAdapterInfo;
        pAdapterInfo:= pAdapterInfo^.Next;
      if assigned(pAdapterInfo) then Dispose(pTempAdapterInfo);
    end;
  finally
    Dispose(pAdapterInfo);

// GetAdaptersAddresses 不属于 Winsock 的东西.
// GetAdaptersAddresses 包含5个参数:
// ULONG Family: 返回的IP类型(IPv4,IPv6或者全部)
// DWORD Flags: 返回一个联合的结构体
// PVOID Reserved: 空
// PIP_ADAPTER_ADDRESSES pAdapterAddresses: 一个指向的缓冲区,当该函数成功执行后,则这个缓冲区将包含得到的IP资讯
// PULONG pOutBufLen:一个指向 pAdapterAddresses结构的指标.
----------------------------------------------
-
作者:
男 keymark (嬲) ▲▲▲△△ -
普通会员
2021/9/21 0:17:18
2楼: https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses
扫网卡 我记得盒子有老程序有码的
articleid
5533
3243
3245
3061
我记得还有个英文的没看到了。。可能搜错key了
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 dalas (dalas) ★☆☆☆☆ -
普通会员
2021/9/21 8:51:25
3楼: @pp0123 (pp0123)

GetAdaptersInfo 无法获取IPv6
----------------------------------------------
-
作者:
男 dalas (dalas) ★☆☆☆☆ -
普通会员
2021/9/21 8:56:10
4楼: @keymark (嬲)

微软的这个范例看过了,但是也没看到转换IP的例子

          pUnicast = pCurrAddresses->FirstUnicastAddress;
          if (pUnicast != NULL) {
          for (i = 0; pUnicast != NULL; i++)
          pUnicast = pUnicast->Next;
          printf("\tNumber of Unicast Addresses: %d\n", i);
          } else
          printf("\tNo Unicast Addresses\n");

          pAnycast = pCurrAddresses->FirstAnycastAddress;
          if (pAnycast) {
          for (i = 0; pAnycast != NULL; i++)
          pAnycast = pAnycast->Next;
          printf("\tNumber of Anycast Addresses: %d\n", i);
          } else
          printf("\tNo Anycast Addresses\n");
----------------------------------------------
-
作者:
男 keymark (嬲) ▲▲▲△△ -
普通会员
2021/9/21 9:08:53
5楼: 数字变IP?  H开头的好象是 估计是记错了

https://www.cnblogs.com/LiuBingBlogs/p/8542168.html

RtlIpv4AddressToString

RtlIpv4AddressToStringEx

RtlIpv4StringToAddress

RtlIpv4StringToAddressEx

RtlIpv6AddressToString

RtlIpv6AddressToStringEx

RtlIpv6StringToAddress

RtlIpv6StringToAddressEx

我记得在盒子下载过一个英文的demo  用来看网卡信息 ip地址 好像是带ipv6的。。
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 dalas (dalas) ★☆☆☆☆ -
普通会员
2021/9/21 13:45:04
6楼: @ keymark (嬲)

这些函数在哪个单元?
----------------------------------------------
-
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2021/9/21 15:28:12
7楼: 首先要给派 IPv6,
我的也祇派 IPv4.
----------------------------------------------
-
作者:
男 keymark (嬲) ▲▲▲△△ -
普通会员
2021/9/22 15:05:44
8楼: 网上抄得代码
有意思得是
#include <Winsock2.h>
#include <ip2string.h>
这两个必须要用 Winsock2不用ip2string 红线杠杠得。

//#pragma comment(lib,"ws2_32.lib")
//#pragma comment(lib,"Ntdll.lib")
//#pragma comment(lib,"iphlpapi.lib")
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <string.h>
#include <Winsock2.h>
#include <ip2string.h>

int main()
{
    PCSTR Terminator = "";
    in_addr Addr;
    if (RtlIpv4StringToAddressA("192.168.0.101", false, &Terminator, &Addr) == STATUS_INVALID_PARAMETER)

    {

        printf("参数错误!");

        return 0;

    }
    std::cout << "Hello World!\n";
    char addr[30] = { 0 };

    RtlIpv4AddressToStringA(&Addr, addr);
    std::cout << addr;
}

\ConsoleApplication1\Debug>ConsoleApplication1.exe
Hello World!
192.168.0.101
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 dalas (dalas) ★☆☆☆☆ -
普通会员
2021/9/22 16:03:03
9楼: 有引用Winsock2,但仍无 RtlIpv4StringToAddressA。
参考了Indy的代码,自己写转换了:
  function InAddrToString(var AInAddr; const AIPVersion: TIdIPVersion): string;
  begin
    case AIPVersion of
      Id_IPv4:
        begin
          //RtlIpv4AddressToString();
          with TIdIn4Addr(AInAddr).S_un_b do
          Result:=Format('%d.%d.%d.%d',[s_b1,s_b2,s_b3,s_b4]);
        end;
      Id_IPv6:
        begin
          //RtlIpv6AddressToString();
          with TIdIn6Addr(AInAddr) do
          Result := Format('%s:%s:%s:%s:%s:%s:%s:%s',
          [NetworkToHost(s6_addr16[0]),
          NetworkToHost(s6_addr16[1]),
          NetworkToHost(s6_addr16[2]),
          NetworkToHost(s6_addr16[3]),
          NetworkToHost(s6_addr16[4]),
          NetworkToHost(s6_addr16[5]),
          NetworkToHost(s6_addr16[6]),
          NetworkToHost(s6_addr16[7])]);
        end;
      else
        begin
          Result := ''; //IPVersionUnsupported;
        end;
    end;
  end;
----------------------------------------------
-
作者:
男 keymark (嬲) ▲▲▲△△ -
普通会员
2021/9/22 16:32:14
10楼: 用系统得调用是sprintf_s
能工作就行了
RtlIpv4AddressToStringA
RtlIpv6AddressToStringA
都是两个参数

         指针          指针
分别是 1(in_addr in6_addr  ) 2(char array) 内存都是由访问程序开好

附件是
Microsoft Visual Studio Community 2022 Preview (64 位)
创建
此帖子包含附件:keymark_202192217615.rar 大小:10.5K
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 keymark (嬲) ▲▲▲△△ -
普通会员
2021/9/22 16:48:40
11楼:    //var AInAddr
TRtlIpv4AddressToStringA = function (addres:pointer;char:pointer): THandle; stdcall;
var
RtlIpv4AddressToStringA: TRtlIpv4AddressToStringA;
var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
cr:array [1..30] of byte;(此处注意内存zero)
cr1:array [1..30] of ansichar;(此处注意内存zero)
begin
cr[1]:=199;
cr[2]:=188;
cr[3]:=1;
cr[4]:=166;
RtlIpv4AddressToStringA := GetProcAddress(GetModuleHandle('NTDLL.DLL'), 'RtlIpv4AddressToStringA');
if not Assigned(RtlIpv4AddressToStringA) then
showmessage('test');
 RtlIpv4AddressToStringA(@cr,@cr1);
 showmessage(cr1);
end;

目前不知道 function  返回得是啥。。。等高手吧。
ipv6 数据格式这个鬼样
byte=20 01:da 8:d 80 0:9 5::1 10
ipv6=2001:da8:d800:95::110(https://ipv6.mirrors.ustc.edu.cn/ ;dns解析得出)
b=4+4+4+4:4+4+4:4+4+4+4:4+4::4+4+4
b=16:12:16:8:12
max=65535:4095:65535:255::4095
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速https://www.cctry.com/>http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行89.84375毫秒 RSS