GCDAsyncSocket客户端在写入之前不读取 [英] GCDAsyncSocket Client not reading until write

查看:47
本文介绍了GCDAsyncSocket客户端在写入之前不读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要包含的代码并不多,但是为什么GCDAsyncSocket客户端可能在读取之前停止,直到将writeData排队为止?症状:

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

  • 尽管服务器调用了"didAcceptNewSocket",但没有调用"didConnectToHost".
  • 服务器写入数据时未调用
  • "didReadData"
  • "socketDidDisconnect"未调用
  • 来自客户端的写入正确传输
  • "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

奇怪的是,调用"writeDelayed"方法(仅使"writeData"方法入队)使所有读取都能得到正确处理.从该方法中删除"writeData"将禁用读取.

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.

这使我认为配置的GCD派遣队列是错误的,因此我尝试了所有可能的新的默认串行和并发队列

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.

可能使事情复杂化的一件事(尽管我不知道如何)是,建立连接是为了响应已解决的NSNetService(Bonjour)对象,该对象可能位于不同的调度队列中.但是我尝试将"setupConnection"包装在要在主队列中执行的块中,无济于事.

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.

谢谢你,詹姆斯

-(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.

这篇关于GCDAsyncSocket客户端在写入之前不读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆