iOS NSStream套接字读取TCP不稳定并被截断

问题描述:

我正在使用以下代码从服务器套接字读取。一切都开始正常,但随着事情的进展,返回的数据会被截断并被错误地分块。我已经阅读了所有尝试不同的东西,例如更改缓冲区大小和同步代码,但仍然没有运气。起初我以为是因为iOS NSStream套接字读取TCP不稳定并被截断

-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { 

异步调用所以我试着同步它,但没有运气那里。我多次增加了缓冲区,但没有运气......我只希望从服务器读取一整行传递给messagedReceived的每次启动它。我确信我正在做一些愚蠢的事情,或者忽视某些对某些人来说显而易见的事情。

-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { 

switch (streamEvent) { 

    case NSStreamEventOpenCompleted: 
     DLog(@"Connection Opened!!!"); 
     [delegate connectionOpened]; 
     break; 

    case NSStreamEventHasBytesAvailable: 

     if (theStream == inputStream) { 



      uint8_t buffer[1024]; 
      int len = 0; 

      while ([inputStream hasBytesAvailable]) { 
       len = [inputStream read:buffer maxLength:sizeof(buffer)]; 

      if (len > 0) { 

        NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding]; 

        if (nil != output) { 
         DLog(@"%@", output); 
         [self messageReceived:output]; 

        } 
       } 
      } 
     } 




     break; 

    case NSStreamEventErrorOccurred: 
     DLog(@"Can not connect to the host!"); 

TCP流是正义的,字节流,它们本身不支持面向消息的和个人的网络数据包可能会被重组,拆分和随意合并。唯一能保证从头到尾的是所有的字节将按照它们发送的顺序到达。你需要自己处理缓冲部分行(或者更频繁的组合行),方法是将它们拆分为新行并保存部分结果。

那么我最终所做的只是寻找行结束字符本人和建设处理它。

-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { 

switch (streamEvent) { 

    case NSStreamEventOpenCompleted: 
     DLog(@"Connection Opened!!!"); 
     [delegate connectionOpened]; 
     break; 

    case NSStreamEventHasBytesAvailable: 

     if (theStream == inputStream) { 



      uint8_t buffer[1024]; 
      int len = 0; 

      while ([inputStream hasBytesAvailable]) { 
       len = [inputStream read:buffer maxLength:sizeof(buffer)]; 

      if (len > 0) { 

        NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding]; 

        if (nil != output) { 
         if ([output rangeOfString:@"\n"].location == NSNotFound) { 

          line = AS(line, output); 

         } else { 



          NSArray *chunks = [output componentsSeparatedByString: @"\n"]; 

          line = AS(line, chunks[0]); 
          [self messageReceived:line]; 
          DLog("M: %@", line); 

          line = chunks[1]; 


         } 



        } 
       } 
      } 
     }