禁用Nagle的NSOutputStreamalgorithm

我正在使用MPCF创build一个多人游戏。 您可以使用iPhone控制iPad上的太空船。

我正在经历不同程度的延迟和延迟以及随机时间和间隔的缓冲/暂停,现在已经登陆Apple Technical Q&A NW26论文,讨论禁用Naglealgorithm。 我试了一下,但我的程序不断崩溃,我不明白为什么。 它似乎是CFWriteStreamCopyProperty总是返回NULL。

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode { switch (eventCode) { case NSStreamEventOpenCompleted: // Trying to get a handle to the native socket CFSocketNativeHandle rawsock; // This always return NULL CFDataRef socketData = CFWriteStreamCopyProperty((__bridge CFWriteStreamRef)(stream), kCFStreamPropertySocketNativeHandle); // And this row always crash (coz of socketData being NULL i guess) CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&rawsock); CFRelease(socketData); // Code example from Apple that need a handle to the native socket, that I am trying to get above int err; static const int kOne = 1; err = setsockopt(rawsock, IPPROTO_TCP, TCP_NODELAY, &kOne, sizeof(kOne)); if (err < 0) { err = errno; } break; default: break; } } 

任何帮助表示赞赏。

你假设这个stream是一个NSOutputStream ,但也可以通过NSInputStream 。 所以它在这条线上崩溃。

这是一个示例代码,可以处理这两种情况并修复崩溃:

 - (void)disableNaglesAlgorithmForStream:(NSStream *)stream { CFDataRef socketData; // Get socket data if ([stream isKindOfClass:[NSOutputStream class]]) { socketData = CFWriteStreamCopyProperty((__bridge CFWriteStreamRef)((NSOutputStream *)stream), kCFStreamPropertySocketNativeHandle); } else if ([stream isKindOfClass:[NSInputStream class]]) { socketData = CFReadStreamCopyProperty((__bridge CFReadStreamRef)((NSInputStream *)stream), kCFStreamPropertySocketNativeHandle); } // get a handle to the native socket CFSocketNativeHandle rawsock; CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&rawsock); CFRelease(socketData); // Disable Nagle's algorythm // Debug info BOOL isInput = [stream isKindOfClass:[NSInputStream class]]; NSString * streamType = isInput ? @"INPUT" : @"OUTPUT"; int err; static const int kOne = 1; err = setsockopt(rawsock, IPPROTO_TCP, TCP_NODELAY, &kOne, sizeof(kOne)); if (err < 0) { err = errno; NSLog(@"Could Not Disable Nagle for %@ stream", streamType); } else { NSLog(@"Nagle Is Disabled for %@ stream", streamType); } } 

case NSStreamEventOpenCompleted:case NSStreamEventOpenCompleted:应该调用这个case NSStreamEventOpenCompleted:

对于任何人想知道为什么复制时不能编译:

 #import <arpa/inet.h> // for IPPROTO_TCP #include <netinet/tcp.h> // for TCP_NODELAY 

但是,这对定期的延迟问题没有帮助。 我仍然在寻找一种方法来防止这种情况发生。

我logging了一个简单的video,演示了这个问题,我相信你遇到了同样的问题: https : //www.dropbox.com/s/omdqkbckph4b1y2/Multipeer%20Connectivity.mov?dl=0

编辑:我能find一种方法来解决定期的延迟问题。 这是导致问题的MCNearbyServiceAdvertiser 。 您需要停止通告对等方,以便消除滞后现象:连接成功后立即在MCNearbyServiceAdvertiser实例上调用stopAdvertisingPeer方法。

 MCNearbyServiceAdvertiser *nearbyServiceAdvertiser; - (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state { switch (state) { case MCSessionStateConnected: { dispatch_async(dispatch_get_main_queue(), ^{ [self.nearbyServiceAdvertiser stopAdvertisingPeer]; }); ... } ... } 

但延迟只会在30秒后closures。 我不知道如何让它消失。