2016-07-19 61 views
0

我有一个程序在经过一些初始处理后通过NSStreams发送大文件。所述应用程序的流程是这样的:执行后台线程后写入NSOutputStream不起作用

1)两个设备彼此连接,打开它们的输入和输出流,并安排它们的运行循环:

[self.inputStream setDelegate:self]; 
    [self.outputStream setDelegate:self]; 
    [self.inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; 
    [self.outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; 
    [self.inputStream open]; 
    [self.outputStream open]; 

2)所述服务器设备发送消息给客户指示一切都很好,我们都准备好了。客户收到这个消息就好了。

3)客户端然后选择它想要发送到服务器并点击“发送”的文件列表。客户端然后分离出一个后台线程来抓取一堆文件并将它们全部压缩。这可能需要一分钟左右的时间。

- (void) sendFilesAtPaths: (NSArray *) paths 
{ 
    self.paths = [paths copy]; 

    __weak FileSharingClient *weakSelf = self; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     for(Item *item in weakSelf.paths) 
     { 
      //Zip files up, this can take some time but we're on a background thread so it won't lock up the UI 
      [weakSelf.connection zipFilesAssociatedWithItem:item]; 
     } 

     //Now that we've done all the heavy work, bounce back to the main thread to actually start sending the data 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      //Start by sending only the first file, the server will let us know when they are ready for the next one 
      [weakSelf.connection sendFileWithItem:weakSelf.paths.firstObject]; 
     }); 
    }); 



} 

4)所述的呼叫“sendFileWithItem:”通过使下面的调用提供的信息的第一脉冲串:

if([_outputStream hasSpaceAvailable]) 
{ 
    NSInteger written = [self.outputStream write:buffer maxLength:self.outputHeaderSize]; 

} 

所有下列数据由通过对- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)streamEvent

进行的呼叫发送数据进行传送

的问题

我看到这里的问题是,我f后台线程压缩这些文件需要较长的时间,初始调用写入数据DOES表示字节已写入流中,但我从不接收任何拨入- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)streamEvent的电话。服务器从不接收信息。在大约30秒后的某个地方,write命令(我假设?)超时,客户端收到一个空字符串(不是由我从服务器明确发送的),并且客户端的连接关闭。

如果我发送的文件不需要很长时间就可以压缩,我不会看到这个问题。

在主线程上运行一切 - 包括压缩过程 - 并不能解决问题(即使忽略它锁定UI的事实)。这似乎排除了线程是一个问题,但现在我只需要继续。

我完全没有想法,我希望有人能帮助我。

注意:对于这个建议,我不能使用CocoaAsyncSockets库。

回答

0

如果有人对这个曾经跌倒起来,恰好看到我看到了同样的事情(和想的一样东西是问题):

问题不在于该线程是造成问题 - 只是写这篇文章让我意识到我的存在是多么的荒谬。问题似乎是在等待这么长时间才能接收数据之后,底层的TCP套接字才会超时。我通过每秒发送一次心跳消息来解决问题,这使得套接字保持活动状态,直到我准备好开始发送数据。