Клиент GCDAsyncSocket не читает до записи

Кода для включения не так много, но почему клиент GCDAsyncSocket может останавливаться при чтении до тех пор, пока writeData не будет поставлен в очередь? Симптомы:

  • «didConnectToHost» не вызывается, хотя сервер вызывает «didAcceptNewSocket».
  • «didReadData» не вызывается, когда сервер записывает данные
  • "socketDidDisconnect" не вызывается
  • записи от клиента передаются правильно

Невероятно странно, но вызов метода «writeDelayed» (который просто ставит в очередь метод «writeData») позволяет правильно обрабатывать все операции чтения. Удаление «writeData» из метода отключает чтение.

Это заставило меня подумать, что настроенная очередь отправки GCD была неправильной, поэтому я попробовал каждую новую и серийную и параллельную очереди по умолчанию.

Или что объект сокета был выпущен раньше времени, поэтому я сделал его свойством класса, но безрезультатно.

Одна вещь, которая может усложнять ситуацию (хотя я не знаю, как), заключается в том, что соединение устанавливается в ответ на разрешенный объект NSNetService (Bonjour), который может находиться в другой очереди отправки. Но я попытался обернуть «setupConnection» в блок, который будет выполняться в основной очереди, но безрезультатно.

Вот небольшое количество кода, отредактирую, если будут вопросы.

Спасибо, Джеймс.

-(void)setupConnection
{
     self.queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);

     self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:self.queue];
}

-(void)connect
{
     NSError *error = nil;
     if(![self.socket connectToHost:self.socketInfo.address onPort:self.socketInfo.port error:&error])
     {
          NSLog(@"I goofed: %@", error);
     }
     NSLog(@"Connecting to: %@:%i",self.socketInfo.address,self.socketInfo.port);
}

-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    NSLog(@"Connected");
    [self.socket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0];
}

-(void)writeDelayed
{
    double delayInSeconds = 2000000.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        NSData* dataObj = [GCDAsyncSocket CRLFData];
        [self.socket writeData:dataObj withTimeout:-1 tag:1];
    });
}
...

person NewEndian    schedule 05.04.2013    source источник


Ответы (1)


Ответ заключается в том, что один из высших объектов в моей цепочке объектов был освобожден раньше, что привело к преждевременному освобождению сокета. Слово мудрым кажется.

person NewEndian    schedule 06.04.2013