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