【问题标题】:NSSocketPortNameServer portForName:host: slow on MavericksNSSocketPortNameServer portForName:host: 小牛慢
【发布时间】:2014-01-13 15:15:44
【问题描述】:

使用 Mavericks [NSSocketPortNameServer portForName:host:] 现在需要大约 5 秒来解析 localhost。它过去要快得多,大约 0.01 秒。

我的代码和Apple's Introduction to Distributed Objects一样。

我曾经能够在不到 0.1 秒的时间内启动子进程并连接到它。 My file manager 运行多个子进程,因此目前在 Mavericks 上已失效。该应用没有沙盒化。

我不明白为什么[NSSocketPortNameServer portForName:host:] 需要这么长时间。也许我做错了什么。

有什么非常感谢的建议吗?


服务器代码

运行大约需要 0.1 秒。

NSSocketPort* port = [[NSSocketPort alloc] init];
NSConnection* connection = [NSConnection connectionWithReceivePort:port sendPort:nil];
[[NSSocketPortNameServer sharedInstance] registerPort:port name:@"doug"];

连接到服务器的客户端代码

这在小牛队需要 5 秒。

过去,Mountain Lion 和 Lion 大约需要 0.1 秒。

NSPort* port = [[NSSocketPortNameServer sharedInstance] portForName:@"doug" host:@"*"];
NSConnection* connection = [NSConnection connectionWithReceivePort:nil sendPort:port];

我也试过nil,比如[[NSSocketPortNameServer sharedInstance] portForName:name host:nil]。没什么区别。

如果我使连接无效并再次尝试连接,那么[[NSSocketPortNameServer sharedInstance] portForName:name host:nil] 也需要 5 秒。


是什么原因造成的

当我使用 scutil --dns 转储 DNS 配置时,我看到本地域有 5 秒的超时。我怀疑这个超时时间在小牛队之前被设置为 0 秒。我不能要求所有用户都重置此超时,因此我将继续调查在 Mavericks 上应采取的措施以避免此超时。

【问题讨论】:

  • 可能与硬件或网络拓扑而不是操作系统有关...我不知道您的测试语义是什么...但是如果它在本地失败并通过某些网络在外部尝试它似乎需要比 .1s 更长的时间
  • @GradyPlayer 听起来很可能。好像它尝试通过 DNS 查找名称,然后最终在本地查找名称。

标签: macos bonjour distributed-objects nsconnection nssocketport


【解决方案1】:

终于解决了。

我最终放弃了-portForName:host:,而是通过命令行将端口号传递给子进程。

子进程以这种方式联系父进程:

int port = /* parent process' port number passed via command line */
NSSocketPort *port = [[NSSocketPort alloc] initRemoteWithTCPPort:port host:nil];
NSConnection* connection = [NSConnection connectionWithReceivePort:nil sendPort:port];

子进程通过命令行从父进程获取端口号。 父进程通过这个类别找到自己的端口号。

@implementation NSSocketPort (ObtainPortNumber)

-(int)portNumber {
        NSSocketNativeHandle sock = [self socket];
        NSData *address = self.address;
        if ([address length] != sizeof(struct sockaddr_in)) {
                NSLog(@"NSSocketPort (ObtainPortNumber) - Mismatch size of address vs size of sockaddr_in.");
                return -1;
        }

        struct sockaddr_in addr = *((struct sockaddr_in*)[address bytes]);

        socklen_t len = sizeof(addr);
        if (getsockname(sock, (struct sockaddr *)&addr, &len) == -1) {
                NSLog(@"NSSocketPort (ObtainPortNumber) - getsockname failed.");
                return -1;
        }

        int portNumber = ntohs(addr.sin_port);
        return portNumber;
}

@end

【讨论】:

    猜你喜欢
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 2013-11-01
    • 1970-01-01
    相关资源
    最近更新 更多