Ios NSNetService解析无法对其发出http请求的ipv6
最近,我在解决Ios NSNetService解析无法对其发出http请求的ipv6,ios,objective-c,xcode,xcode6.1,ios8.1,Ios,Objective C,Xcode,Xcode6.1,Ios8.1,最近,我在解决NSNetService时遇到了一个问题 我发布了一个类型为http.\u tcp.的NSNetService,就像http服务器一样。 另一方面,在另一台设备上,我开始搜索这个服务,它会找到它 找到它后,我在上面应用了resolveWithTimeout 在解析过程中,有时我只获取ipv6,无法使用NSURLConnection sendAsynchronousRequest:queue:completionHandler:对其进行HTTPRequest 如何在url上应用和HT
NSNetService
时遇到了一个问题
我发布了一个类型为http.\u tcp.的NSNetService
,就像http服务器一样。
另一方面,在另一台设备上,我开始搜索这个服务,它会找到它
找到它后,我在上面应用了resolveWithTimeout
在解析过程中,有时我只获取ipv6,无法使用NSURLConnection sendAsynchronousRequest:queue:completionHandler:
对其进行HTTPRequest
如何在url上应用和HTTPRequest包含ipv6?
如何处理该问题?看起来您正在根据
NSNetService
中提供的信息构建一个类似http://{IP}:{port}/
的字符串。对于IPv4地址,它可以正常工作,结果字符串类似于http://192.168.1.8:8080/
但是,IPv6地址使用冒号作为分隔符(而不是句点),因此相同的代码会生成类似http://fe80::e31:db5a:0089:98ba:8080/
,并且生成的地址不正确。首先,您需要将地址用方括号括起来:http://[fe80::e31:db5a:0089:98ba]:8080/
。其次,fe80::/64(如示例中所示)地址是本地链接地址,可以分配给每个支持IPv6的接口,因此您还需要提供要使用的接口,例如http://[fe80::e31:db5a:0089:98ba%25en0]:8080/
其中%25
是编码的百分比符号,en0
是要使用的接口名称
总之,您需要为IPv4和IPv6地址构建不同的字符串。说到这里,苹果公司提出了以下建议:
通常,除非您正在做一些非常不寻常的事情,否则不应该将服务解析为IP地址和端口号。
–
如果可能,尝试使用此URL字符串:http://{hostname}:{port}/
,您将不需要这些额外的IP地址操作。看起来您正在基于NSNetService
中提供的信息构建一个类似http://{IP}:{port}/
的字符串。对于IPv4地址,它可以正常工作,结果字符串类似于http://192.168.1.8:8080/
但是,IPv6地址使用冒号作为分隔符(而不是句点),因此相同的代码会生成类似http://fe80::e31:db5a:0089:98ba:8080/
,并且生成的地址不正确。首先,您需要将地址用方括号括起来:http://[fe80::e31:db5a:0089:98ba]:8080/
。其次,fe80::/64(如示例中所示)地址是本地链接地址,可以分配给每个支持IPv6的接口,因此您还需要提供要使用的接口,例如http://[fe80::e31:db5a:0089:98ba%25en0]:8080/
其中%25
是编码的百分比符号,en0
是要使用的接口名称
总之,您需要为IPv4和IPv6地址构建不同的字符串。说到这里,苹果公司提出了以下建议:
通常,除非您正在做一些非常不寻常的事情,否则不应该将服务解析为IP地址和端口号。
–
如果可能,尝试使用此URL字符串:http://{hostname}:{port}/
,您将不需要这些额外的IP地址操作。看起来您正在基于NSNetService
中提供的信息构建一个类似http://{IP}:{port}/
的字符串。对于IPv4地址,它可以正常工作,结果字符串类似于http://192.168.1.8:8080/
但是,IPv6地址使用冒号作为分隔符(而不是句点),因此相同的代码会生成类似http://fe80::e31:db5a:0089:98ba:8080/
,并且生成的地址不正确。首先,您需要将地址用方括号括起来:http://[fe80::e31:db5a:0089:98ba]:8080/
。其次,fe80::/64(如示例中所示)地址是本地链接地址,可以分配给每个支持IPv6的接口,因此您还需要提供要使用的接口,例如http://[fe80::e31:db5a:0089:98ba%25en0]:8080/
其中%25
是编码的百分比符号,en0
是要使用的接口名称
总之,您需要为IPv4和IPv6地址构建不同的字符串。说到这里,苹果公司提出了以下建议:
通常,除非您正在做一些非常不寻常的事情,否则不应该将服务解析为IP地址和端口号。
–
如果可能,尝试使用此URL字符串:http://{hostname}:{port}/
,您将不需要这些额外的IP地址操作。看起来您正在基于NSNetService
中提供的信息构建一个类似http://{IP}:{port}/
的字符串。对于IPv4地址,它可以正常工作,结果字符串类似于http://192.168.1.8:8080/
但是,IPv6地址使用冒号作为分隔符(而不是句点),因此相同的代码会生成类似http://fe80::e31:db5a:0089:98ba:8080/
,并且生成的地址不正确。首先,您需要将地址用方括号括起来:http://[fe80::e31:db5a:0089:98ba]:8080/
。其次,fe80::/64(如示例中所示)地址是本地链接地址,可以分配给每个支持IPv6的接口,因此您还需要提供要使用的接口,例如http://[fe80::e31:db5a:0089:98ba%25en0]:8080/
其中%25
是编码的百分比符号,en0
是要使用的接口名称
总之,您需要为IPv4和IPv6地址构建不同的字符串。说到这里,苹果公司提出了以下建议:
通常,除非您正在做一些非常不寻常的事情,否则不应该将服务解析为IP地址和端口号。
–
如果可能,请尝试使用此URL字符串:http://{hostname}:{p
NSString * result = nil;
char host[NI_MAXHOST];
char service[NI_MAXSERV];
int err;
err = getnameinfo(address.bytes, (socklen_t) address.length, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV);
if (err == 0) {
struct sockaddr_storage *sockaddr = (struct sockaddr_storage *)address.bytes;
if (sockaddr->ss_family == AF_INET6) {
result = [NSString stringWithFormat:@"[%s]:%s", host, service];
} else if (sockaddr->ss_family == AF_INET) {
result = [NSString stringWithFormat:@"%s:%s", host, service];
}
}