わかった。したがって、NSStreamDelegate の実装のために処理しなければならない例外的なケースがあります。
プロセスは次のとおりです。
1- COMMAND データが出力ストリームに書き込まれ、もう一方の端がトリガーされます
2-もう一方の端は、入力ストリームのデータを非同期に配置し始めます。つまり、データの最初の部分が最初に受信され、数秒後に残りのデータが受信されます。
3- すべてのデータが受信された後、サーバーはデータを送信しませんが、接続は開いたままです。(入力ストリームのステータス = オープン (2))
4- 数分後、サーバーは接続を終了し (入力ストリームのステータス = 5)、NSStreamEventEndEncountered がトリガーされます。
SendRequest クラス
- (void)sendSecondRequest {
CFReadStreamRef readStream = nil;
CFWriteStreamRef writeStream = nil;
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)self.SOMEServer, self.SOMEPort, &readStream, &writeStream);
self.inputStream = (__bridge NSInputStream *)readStream;
self.outputStream = (__bridge NSOutputStream *)writeStream;
[self.inputStream setDelegate:self];
[self.outputStream setDelegate:self];
NSData *data = [NSData dataWithData:[kSecondCall dataUsingEncoding:NSASCIIStringEncoding]];
[self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.inputStream open];
[self.outputStream open];
[self.outputStream write:[data bytes] maxLength:[data length]];
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
switch (eventCode) {
case NSStreamEventOpenCompleted:
break;
case NSStreamEventHasBytesAvailable:
if (aStream == self.inputStream) {
uint8_t buffer[1024];
NSInteger len = [self.inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
[gOutput appendString:output];
}
}
break;
case NSStreamEventEndEncountered:
NSLog(@"Can not connect to the host");
[aStream close];
[aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
aStream = nil;
break;
default:
break;
}
}
- (void)disconnectSocket {
[self.inputStream close];
[self.inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.outputStream close];
[self.outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.inputStream setDelegate:nil];
[self.outputStream setDelegate:nil];
self.inputStream = nil;
self.outputStream = nil;
}
gOutput変数は、入力ストリームの読み取りと保存に使用するグローバル変数です。
問題は、データの最初の部分がすぐに到着し、残りが非同期に到着するため、利用可能なデータがなくなった瞬間を処理できないことです。
つまり、サーバーがデータの送信を完了し、処理を開始する必要があるかどうかをどのように知ることができますか?