首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >IP地址出错

IP地址出错
EN

Stack Overflow用户
提问于 2014-01-30 21:34:43
回答 1查看 1.3K关注 0票数 0

我正在尝试自动检测和报告Delphi编程的IPv6可用性。

对于"localhost",以下代码返回IPv6的"1700::“和IPv4的"2.0.0.0”。此地址用于简单测试,并应返回::1或127.0.0.1用于我的机器。我在调用代码中没有任何套接字API错误,所以我试图找出我在尝试将"localhost“转换为各种IP地址时做错了什么。我在用印第标头。

类型声明是:

代码语言:javascript
运行
复制
TLSocketAddress = record
  case Integer of
    AF_INET:
      (IPv4: TSockAddrIn);
    AF_INET6:
      (IPv6: TSockAddrIn6);
end;

TLIpInfo = record
private
  function GetFamily: TProtocolFamily;
public
  Address : TLSocketAddress;
  HostName: string;
  Machine: string;
  IP6 : string;
  IP4 : string;
  Port : integer;
  Error : integer;
  property Family : TProtocolFamily read GetFamily;
end;

检索例程是:

代码语言:javascript
运行
复制
function GetIpInfo(
  const AHostName : string;
  const APort     : integer
  ): TLIpInfo;
var
  nameRet   : PAnsiChar;
  ptr       : Pointer;
  Hints     : TAddrInfoW;
  AddrInfo  : PAddrInfoW;
  NextInfo  : PAddrInfoW;
  RetVal    : Integer;
  ip,
  machine   : string;
  namelen   : integer;
begin
  ZeroMemory(@Result, SizeOf(Result));
  FillChar(Hints, SizeOf(Hints), 0);
  Hints.ai_family := AF_UNSPEC;

  AddrInfo := nil;
  RetVal := GetAddrInfo(PWideChar(AHostName), nil, @Hints, @AddrInfo);
  if RetVal = 0 then
  try
    Result.HostName := AHostName;
    Result.Port := APort;
    NextInfo := AddrInfo;
    while NextInfo <> nil do
    begin
      if (NextInfo.ai_family = AF_INET) or (NextInfo.ai_family = AF_INET6) then
      begin
        if (Result.Machine = '') then
        begin
          SetLength(machine, NI_MAXHOST);
          RetVal := GetNameInfo(NextInfo.ai_addr, NextInfo.ai_addrlen,
            PChar(machine), NI_MAXHOST, nil, 0, 0);
          if (RetVal <> 0) then
          begin
            NextInfo := NextInfo.ai_next;
            continue;
          end;
          Result.Machine := PChar(machine);
        end;

        if NextInfo.ai_family = AF_INET then
        begin
          ptr := PSockAddrIn(NextInfo.ai_addr);
          namelen := INET_ADDRSTRLEN;
          SetLength(ip, namelen);
        end
        else
        begin
          ptr := PSockAddrIn6(NextInfo.ai_addr);
          namelen := INET6_ADDRSTRLEN;
          SetLength(ip, namelen);
        end;

        nameRet := inet_ntop(NextInfo.ai_family, ptr, PChar(ip), namelen);
        if (nameRet = nil) then
        begin
          NextInfo := NextInfo.ai_next;
          continue;
        end;

        if (NextInfo.ai_family = AF_INET6) then
          Result.IP6 := PChar(ip)
        else
          Result.IP4 := PChar(ip);
      end;
      NextInfo := NextInfo.ai_next;
    end;
  finally
    FreeAddrInfo(AddrInfo);
  end;
end;
EN

回答 1

Stack Overflow用户

发布于 2015-10-23 12:14:33

我知道对作者来说可能为时已晚,但我今天遇到了同样的问题,我注意到您将指向整个ADDRINFO结构的指针传递给inet_ntop,但是您只应该传递指向二进制地址的指针。

因此,调用intet_ntop for IPv4地址应该是:

代码语言:javascript
运行
复制
inet_ntop(NextInfo.ai_family, @PSockAddrIn(NextInfo.ai_addr).sin_addr, PChar(ip), namelen)

对于IPv6应该是:

代码语言:javascript
运行
复制
inet_ntop(NextInfo.ai_family, @PSockAddrIn6(NextInfo.ai_addr).sin6_addr, PChar(ip), namelen)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21467860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档