2014-11-03 149 views
0

最近,我在解決NSNetService時遇到問題。NSNetService解決無法發出http請求的ipv6

我發佈了一個NSNetService,類型_http._tcp.,就像一個http服務器。 其他方面,在另一臺設備上,我開始搜索這項服務,它會找到它。

找到它後,我申請了resolveWithTimeout就可以了。

雖然解決,有時我只得到ipv6,我不能使用NSURLConnection sendAsynchronousRequest: queue: completionHandler:上的HTTPRequest。

我如何申請和HTTPRequest上的url包含ipv6? 我該如何處理這個問題?

回答

3

看起來您正在根據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地址和端口號,除非你正在做非常不尋常的事情。 - Connecting to a Bonjour Service by IP Address

嘗試使用此URL字符串如果可能的話:http://{hostname}:{port}/,您將不再需要這些額外的IP地址的操作。

+0

我試圖找到我怎麼能找到的接口名稱 - 但我不能,你能請把我指向正確的方向?就像我知道它的en0或en1等。 – 2017-10-26 18:40:01

+0

@CherpakEvgeny AFAIK'en0'是iOS中WiFi的標準接口名稱。你也可以遍歷可用的接口:https://stackoverflow.com/a/13279757/635603 – eugene 2017-11-01 03:45:28

+0

看到我的答案吼 – 2017-11-04 01:02:47

0

原來這就是我最終使用...它正確地轉換地址轉換成URL包括接口:

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]; 
    } 
}