NSSocketPortNameServer portForName:host: slow на Mavericks

С Маверикс [NSSocketPortNameServer portForName:host:] теперь требуется около 5 секунд для разрешения localhost. Раньше все было намного быстрее, около 0,01 секунды.

Мой код такой же, как во введении Apple к распределенным объектам.

Раньше я мог запускать дочерний процесс и подключаться к нему менее чем за 0,1 секунды. Мой файловый менеджер запускает несколько дочерних процессов и в настоящее время не работает на 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 секунд на Маверикс.

Раньше на Горного Льва и Льва уходило около 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 секунд.


Что может быть причиной этого

Когда я сбрасываю конфигурацию DNS с scutil --dnsЯ вижу, что локальный домен имеет 5-секундный тайм-аут. Я подозреваю, что этот тайм-аут был установлен на 0 секунд до Mavericks. Я не могу попросить всех пользователей сбросить этот тайм-аут, поэтому я продолжу исследовать, что делать на Mavericks, чтобы избежать этого тайм-аута.

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
Другие вопросы по тегам