gpt4 book ai didi

ios - 禁用 Nagle 的 NSOutputStream 算法

转载 作者:可可西里 更新时间:2023-11-01 04:38:57 27 4
gpt4 key购买 nike

我正在使用 MPCF 创建多人游戏.您可以使用 iPhone 在 iPad 上控制 spaceship 。

我在随机时间和间隔遇到各种延迟和延迟以及缓冲/暂停,现在已经登陆苹果 Technical Q&A NW26讨论禁用 Nagle 算法的论文。我正在尝试,但我的程序一直崩溃,我不明白为什么。似乎是 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:

中调用

对于任何想知道为什么在复制粘贴时它无法编译的人:

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

但是,它无助于解决周期性延迟问题。我仍在寻找防止这种情况发生的方法。

我录制了一段演示该问题的简单视频,相信您也遇到了同样的问题: https://www.dropbox.com/s/omdqkbckph4b1y2/Multipeer%20Connectivity.mov?dl=0

编辑:我找到了解决周期性延迟问题的方法。导致问题的是 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 秒 后关闭。我不知道如何让它立即消失。

关于ios - 禁用 Nagle 的 NSOutputStream 算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23810373/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com