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