2017-03-08 23 views
0

如果數據在服務器上短暫延遲後發送,則輸入流正常工作。問題是只有當服務器在收到數據後立即做出響應。我在同一個類中處理輸入和輸出流。輸入流調用事件NSStreamEventHasBytesAvailable,但流不包含字節

創建流:

// STREAMS 
CFReadStreamRef readStream; 
CFWriteStreamRef writeStream; 

// CREATE READABLE/WRITABLE STREAMS TO HOST/PORT 
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)terminalIp, [terminalPort intValue], &readStream, &writeStream); 

// SET STREAMS 
inputStream = (__bridge NSInputStream *)readStream; 
outputStream = (__bridge NSOutputStream *)writeStream; 

// SETTING DELEGATES 
[inputStream setDelegate:self]; 
[outputStream setDelegate:self]; 

// SET LOOP TO LISTEN FOR MESSAGES 
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

// OPEN STREAMS 
[inputStream open]; 
[outputStream open]; 

流委託事件處理程序:

//////////////////////////////////// 
// FUNCTION - STREAM EVENT HANDLER 
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{ 

// LOG 
if(aStream == outputStream){ 

    NSLog(@"Status of outputStream: %lu", (unsigned long)[outputStream streamStatus]); 

}else{ 

    NSLog(@"Status of inputStream: %lu", (unsigned long)[inputStream streamStatus]); 

} 

// 
// CHECK EVENTS 
// 

if(eventCode == NSStreamEventOpenCompleted){ 

    // 
    // STREAM OPEN 
    // 


}else if(eventCode == NSStreamEventHasBytesAvailable){ 

    // 
    // SERVER SENT BYTES 
    // 

    // CHECK STREAM TYPE 
    if(aStream == inputStream){ 

     // SETTINGS 
     uint8_t buffer[1024]; 

     // LOOP WHILE THERE ARE BYTES BEING RECIVED 
     while ([inputStream hasBytesAvailable]){ 

      // MAKE SURE THERE ARE BYTES 
      if([inputStream read:buffer maxLength:sizeof(buffer)] > 0){ 

       // SET HEX RESPONSE 
       hexResponse = [[NSData alloc] initWithBytes:buffer length:[inputStream read:buffer maxLength:sizeof(buffer)]]; 

       NSLog(@"hex in stream: %@",hexResponse); 

       NSString *incomingString; 

       if (hexResponse.length >= 2){ 


        // TURN HEX INTO STRING 
        incomingString = [[NSString alloc] initWithData:hexResponse encoding:NSUTF8StringEncoding]; 
        NSLog(@"%@", incomingString); 

       } 


       // MAKE SURE THERE IS TEXT THERE 
       if(incomingString.length > 3){ 

        // SET TEXT 
        stringResponse = incomingString; 

       } 

      } 

     } 

    } 

}else if(eventCode == NSStreamEventErrorOccurred){ 

    // 
    // COULDN'T CONNECT 
    // 

    NSError *theError = [aStream streamError]; 

    NSLog(@"Stream Error (%ld): %@",(long)[theError code],[theError localizedDescription]); 


}else if(eventCode == NSStreamEventEndEncountered){ 

    // 
    // END 
    // 

    // CHECK STREAM TYPE 
    if(aStream == outputStream){ 

     NSData *newData = [outputStream propertyForKey: 
          NSStreamDataWrittenToMemoryStreamKey]; 
     if (!newData) { 
      NSLog(@"No data written to memory from output stream!"); 
     } else { 
      //[self processData:newData]; 
      // CONVERT 
      //[self translateResponse]; 
     } 
     [outputStream close]; 
     [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] 
          forMode:NSDefaultRunLoopMode]; 

     outputStream = nil; 





    }else if(aStream == inputStream){ 

     NSData *newData = [inputStream propertyForKey: 
          NSStreamDataWrittenToMemoryStreamKey]; 
     if (!newData) { 
      NSLog(@"No data written to memory from input stream!"); 
     } else { 
      NSLog(@"Data found in input stream!"); 

      //[self processData:newData]; 
      // CONVERT 
      [self translateResponse]; 
     } 
     [inputStream close]; 
     [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] 
           forMode:NSDefaultRunLoopMode]; 

     inputStream = nil; 

    } 


}else if(eventCode == NSStreamEventHasSpaceAvailable){ 

    // 
    // HAS SPACE TO SEND 
    // 

    if(aStream == outputStream){ 
    NSMutableData * dataToSend = [NSMutableData dataWithData:hexRequest]; 

     uint8_t *readBytes = (uint8_t *)[dataToSend mutableBytes]; 
     readBytes += byteIndex; // instance variable to move pointer 
     NSUInteger data_len = [dataToSend length]; 
     unsigned long len = ((data_len - byteIndex >= 1024) ? 
          1024 : (data_len-byteIndex)); 
     uint8_t buf[len]; 
     (void)memcpy(buf, readBytes, len); 
     len = [outputStream write:(const uint8_t *)buf maxLength:len]; 
     byteIndex += len; 

    } 


}else{ 

    // 
    // UNKNOWN EVENT 
    // 

} 

} // END FUNCTION 

回答

0

問題是由讀取輸入緩衝器兩次造成的。我在條件聲明中以及在我分配它時閱讀了它。問題通過首先分配來解決。

新代碼:

}else if(eventCode == NSStreamEventHasBytesAvailable){ 

    // 
    // SERVER SENT BYTES 
    // 

    // CHECK STREAM 
    if(aStream == inputStream){ 

     // SSET BUFFER 
     uint8_t buffer[1024]; 

     // LOOP WHILE THERE ARE BYTES BEING RECIVED 
     while ([(NSInputStream *)aStream hasBytesAvailable]){ 

      // READ BUFFER 
      hexResponse = [[NSData alloc] initWithBytes:buffer length:[(NSInputStream *)aStream read:buffer maxLength:sizeof(buffer)]]; 

      // MAKE SURE THERE IS DATA 
      if([hexResponse length] > 0){ 

       // INIT INCOMING STRING 
       NSString *incomingString; 

       // MAKE SURE RESPONSE IS NOT A HEARTBEAT 
       if (hexResponse.length >= 2){ 

        // TURN HEX INTO STRING 
        incomingString = [[NSString alloc] initWithData:hexResponse encoding:NSUTF8StringEncoding]; 
        NSLog(@"%@", incomingString); 

       } 


       // MAKE SURE INCOMING STRING IS VALID 
       if(incomingString.length > 3){ 

        // SET TEXT 
        stringResponse = incomingString; 

       } 

      } 

     } 

    } 

}