NSinputstream读取数据返回空值?

时间:2016-06-16 09:22:09

标签: ios objective-c nsstream

在我的应用中,我使用NSStreams进行客户端服务器通信。事件delegate中的hasbytesAvailable方法在我读取数据时返回null

案例:当长度为4096时,读取失败并返回nil;意味着当长度等于缓冲区大小时它无法读取,即使我将maxlength设置为4000并且缓冲区大小为4096,那么每当读取4000个字节时它也会失败。该怎么办?

以下是代码:

case NSStreamEventHasBytesAvailable:

     if (aStream == inputStream) {
             uint8_t buffer[4096];
             int len;
             while ([inputStream hasBytesAvailable]) {                      
                 len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
                 NSLog(@"\nThe length is -- %d\n",len);
                     if (len > 0) {
                            NSData *data = [[NSData alloc] initWithBytes:buffer length:len];
                            output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                              // output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];                            
                              }
                  }
               }         

         NSLog(@"\n\n%@\n\n",output);

2 个答案:

答案 0 :(得分:1)

从网络连接读取的数据并不总是以发送的相同大小的块接收。这意味着接收方需要:

  1. 确切了解邮件中预计会有多少数据。
  2. 记住任何"遗留下来"来自当前消息的数据属于下一条消息。
  3. 正确执行此操作的最简单方法之一是在消息前加上字节数,然后只尝试从网络连接中读取那么多数据。这会在"网络缓冲区中留下任何剩余的数据"直到客户想要它。

    您的代码正在接收一个字符串,该字符串将被NUL终止,这意味着您需要以固定大小的块读取数据,检查每个字节,直到找到字符串结尾,然后在将块转换为字符串之前将块粘在一起。然后你需要记住任何"遗留的"下一条消息的数据。复杂的东西,嗯?

    我会使用邮件大小前缀,因为这是其他人所做的事情。

答案 1 :(得分:0)

我认为代码绝对正常并且它应该读取数据,可能在您读取4096字节后可能有更多字节可用并且循环继续,并且您再次初始化输出变量,所以你可能会错过它。

使用以下代码段:

self.edgesForExtendedLayout = UIRectEdgeRight | UIRectEdgeLeft | UIRectEdgeBottom;