如何配置Indy v10以支持IPv4 + IPv6?

10
使用以下代码,我可以获取IPv4网站的内容:
uses 
  IdHttp;

IdHttp1 := TIdHttp.Create(nil);
try
  Result := IdHttp1.Get('http://www.heise.de/')
finally
  IdHttp1.Free;
end;

但是当我尝试连接IPv6网站时,出现套接字错误#11004:

IdHttp1 := TIdHttp.Create(nil);
try
  Result := IdHttp1.Get('http://www.six.heise.de/')
finally
  IdHttp1.Free;
end;

我可以正常ping通www.six.heise.de(IP 2a02:2e0:3fe:100::6),并且Firefox也能正常显示该网站。

我需要在Indy中进行哪些更改(最新的SVN版本V10构建),才能连接IPv4和IPv6网站?

1个回答

12

TIdTCPClient需要告知使用IPv4还是IPv6进行套接字和主机名到IP地址的解析。这可以通过TIdTCPClient.IPVersion属性来实现。但是,TIdHTTP是一个特殊情况,因为它在内部管理TIdTCPClient属性和连接,包括IPVersionTIdHTTP基于请求的URL设置IPVersion。为了请求包含IPv6主机名的URL,它需要用括号括起来,例如:

Result := IdHttp1.Get('http://[www.six.heise.de]/')

1
这个方法可以运行,但是它是一个相当奇怪的解决方案,因为Web浏览器不会接受http://[www.six.heise.de]/。有没有一种方法来确定一个网站是IPv4还是IPv6,在IPv6的情况下将括号添加到URL中? - Casady
2
在URL中使用的IPv6地址必须加上括号,根据RFC 2732规定。主机名不需要加括号,但是TIdHTTP目前没有其他方式事先知道何时使用IPv4和IPv6。当Web浏览器连接到URL时,它通过DNS解析主机名以获取其可用的IPv4 / IPv6地址,然后尝试连接到它们直到其中一个成功为止。TIdTCPClient在设置了IPVersion并创建了IPv4 / IPv6套接字之后才解析主机名。它不会尝试连接到多个IP。这可能在未来需要改变。 - Remy Lebeau
5
目前,您可以使用TIdDNSResolver手动执行主机名的DNS查找,然后使用格式正确的URL使用TIdHTTP - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接