質問

It's not much code to include, but why might a GCDAsyncSocket client stall on reads until a writeData is queued? Symptoms:

  • "didConnectToHost" doesn't get called though the server calls "didAcceptNewSocket'.
  • "didReadData" doesn't get called when the server writes data
  • "socketDidDisconnect" does not get called
  • writes from the client get transmitted properly

Incredibly oddly, calling the "writeDelayed" method (which merely enqueues the "writeData" method) enables all reads to be processed properly. Removing "writeData" from the method disables the reads.

This made me think that the configured GCD dispatch queue was wrong so I tried every new and default serial and concurrent queue possible

Or that the socket object was being released before its time, so I made it a class property, to no avail.

One thing that may be complicating things (though I don't know how), is that the connection is being made in response to a resolved NSNetService (Bonjour) object, which might be on a different dispatch queue. But I tried wrapping "setupConnection" in a block to be executed on the main queue, to no avail.

Here's a small amount of code, I'll edit if there are any questions.

Thank you, James

-(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];
    });
}
...
役に立ちましたか?

解決

The answer is that one of the higher objects in my object chain was released early, causing the socket to be released early as well. Word to the wise it seems.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top