如果在服务器上发生短暂延迟后发送数据,则输入流工作正常。仅当服务器在收到数据后立即做出响应时才会出现问题。我在同一个类中处理输入和输出流。
// 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 :(得分: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;
}
}
}
}
}