我尝试自动检测并报告Delphi套接字编程的IPv6可用性。
对于" localhost",以下代码返回" 1700 ::"对于IPv6和" 2.0.0.0"对于IPv4。此地址用于简单测试,应该为我的机器返回:: 1或127.0.0.1。我在调用代码中没有收到任何套接字API错误,所以我试图弄清楚我在尝试转换" localhost"时做错了什么。到各种IP地址。我正在使用Indy标题。
类型声明是:
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;
,检索程序为:
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;
答案 0 :(得分:1)
我知道这对作者来说可能为时已晚,但我今天也遇到了同样的问题,并注意到你将指向整个 ADDRINFO 结构的指针传递给 inet_ntop 但是,您应该只将指针传递给二进制地址 因此,对 IPv4 地址的 intet_ntop 的调用应为:
inet_ntop(NextInfo.ai_family, @PSockAddrIn(NextInfo.ai_addr).sin_addr, PChar(ip), namelen)
和 IPv6 应为:
inet_ntop(NextInfo.ai_family, @PSockAddrIn6(NextInfo.ai_addr).sin6_addr, PChar(ip), namelen)