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