[英]GCDAsyncUdpSocket immediately closes when sending to an IPv6 address
我通过UDP连接到Bonjour公布的其他设备上的服务器。 当运行此代码的iOS设备和服务器都在我们的wifi网络上时,它工作正常,因为bonjour服务解析为我们的dhcp服务器发出的192.168.0.xxx地址。 然而,当它通过蓝牙做广告时,有时服务解析为169.254.xxx.xxx(IPv4),在这种情况下它可以正常工作。 但有时它解析为fe80 :: xxxx:xxxx:xxxx:xxxx(IPv6),在这种情况下套接字连接(我收到udpSocket:didConnectToAddress
回调)但在我尝试发送数据时立即关闭(我立即收到udpSocketDidClose:withError
回调在致电发送时)。
- (BOOL) setupConnection: (DNSSDService*) service
{
NSString *host = [service resolvedHost];
NSUInteger port = [service resolvedPort];
NSLog(@"in setupConnection: host %@ port %u",
host, port);
self.sock = [[GCDAsyncUdpSocket alloc]initWithDelegate:self
delegateQueue:dispatch_get_main_queue() ];
NSError *err = nil;
if (![self.sock connectToHost:host onPort:port error:&err]) {
NSLog(@"we goofed: %@", err);
return NO;
}
return YES;
}
我的udpSocket:didConnectToAddress
方法调用一个send,而我的其他回调基本上只是信息(NSLog)。 这是传递给udpSocketDidClose:withError
的NSError udpSocketDidClose:withError
:
Error Domain=GCDAsyncUdpSocketErrorDomain Code=4 "Socket closed" UserInfo=0x2630c0 {NSLocalizedDescription=Socket closed}
不太有用。
在修复这个问题时,我想让它与IPv6协同工作而不是强制IPv4 ...强迫IPv4对我来说似乎很脆弱。
fe80是链路本地IPv6地址。 您要连接的机器必须具有多个网络接口 - 大部分都是,例如以太网和WiFi。 要完全特定IPv6地址,scope_id是必需的。 这是来自的sin6_scope_id:
// IPv6 AF_INET6 sockets:
struct sockaddr_in6 {
u_int16_t sin6_family; // address family, AF_INET6
u_int16_t sin6_port; // port number, Network Byte Order
u_int32_t sin6_flowinfo; // IPv6 flow information
struct in6_addr sin6_addr; // IPv6 address
u_int32_t sin6_scope_id; // Scope ID
};
当与地址结合并转换为字符串时,如下所示: fe80::e2f8:47ff:fe23:5392%eth1
解析DNS后,包装sockaddr
结构的NSData
包含此信息。 然而,在你的代码,你提取sin6_port
和sin6_addr
,然后喂它们回到GCDAsyncUDPSocket
泯灭的sin6_flowinfo
(你不需要)和sin6_scope_id
(在这种情况下,你这样做)。
直接使用-[GCDAsyncUDPSocket connectToAddress:error:]
,使用直接从您的解析服务获得的NSData
,您应该好好去。
我所做的是在套接字上调用setPreferIPv4
和setIPv6Enabled:FALSE
,如果DNS查找仅返回IPv6地址,则会导致连接失败。 然后,在udpSocket:didNotConnect:
我检查了该特定错误( IPv6 has been disabled and DNS lookup found no IPv4 address(es).
)如果连接因此失败,请返回我的setupConnection
方法并再次尝试。 最终DNS查找返回一个IPv4地址,事情从那里顺利进行。
这不是最优雅的解决方案,但它确实有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.