6

全て、

通信用の tcp ソケット ストリームを持つサーバーがあります。そのストリームにアクセスして、送信する必要がある初期データを読み取る必要があります。

私の現在のコードは次のとおりです。正直なところ、私はこれを完全に盲目的に行っています。これが正しいかどうか、ましてや仕事に適しているかどうかはわかりません。

-(void) initNetworkCommunication
{
    //input stream
    NSInputStream *iStream;
    NSURL *url = [url initWithString:@"192.168.17.1:2004"];

    [iStream initWithURL:url];
    [iStream setDelegate:self];
    [iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [iStream open];

}

私の見方では、このコードはストリームを初期化しますが、ストリームからどのように読み取るのですか?

ありがとう

4

2 に答える 2

23

ストリームからデータを取得するには、ポーリングとストリーム イベントの使用の 2 つの方法があります。

ポーリングはより単純ですが、実行中のスレッドをブロックします。このメソッドを使用する場合、setDelegate:またはscheduleInRunLoop:forMode:呼び出しを実行する必要はありません。を繰り返し呼び出すことでポーリングを行いread:maxLength:ます。

NSInteger result;
uint8_t buffer[BUFFER_LEN]; // BUFFER_LEN can be any positive integer
while((result = [iStream read:buffer maxLength:BUFFER_LEN]) != 0) {
    if(result > 0) {
        // buffer contains result bytes of data to be handled
    } else {
        // The stream had an error. You can get an NSError object using [iStream streamError]
    }
}
// Either the stream ran out of data or there was an error

ストリーム イベントを使用するには、デリゲートを設定し、ストリームを実行ループに追加する必要があります。ストリームは、スレッドをブロックする代わりに、stream:handleEvent:データの受信時など、特定のイベントが発生したときにデリゲートにメッセージを送信します。その後、デリゲートはストリームからデータを取得できます。stream:handleEvent:メソッドの例を次に示します。

- (void)stream:(NSInputStream *)iStream handleEvent:(NSStreamEvent)event {
    BOOL shouldClose = NO;
    switch(event) {
        case  NSStreamEventEndEncountered:
            shouldClose = YES;
            // If all data hasn't been read, fall through to the "has bytes" event
            if(![iStream hasBytesAvailable]) break;
        case NSStreamEventHasBytesAvailable: ; // We need a semicolon here before we can declare local variables
            uint8_t *buffer;
            NSUInteger length;
            BOOL freeBuffer = NO;
            // The stream has data. Try to get its internal buffer instead of creating one
            if(![iStream getBuffer:&buffer length:&length]) {
                // The stream couldn't provide its internal buffer. We have to make one ourselves
                buffer = malloc(BUFFER_LEN * sizeof(uint8_t));
                freeBuffer = YES;
                NSInteger result = [iStream read:buffer maxLength:BUFFER_LEN];
                if(result < 0) {
                    // error copying to buffer
                    break;
                }
                length = result;
            }
            // length bytes of data in buffer
            if(freeBuffer) free(buffer);
            break;
        case NSStreamEventErrorOccurred:
            // some other error
            shouldClose = YES;
            break;
    }
    if(shouldClose) [iStream close];
}
于 2011-07-14T03:20:08.647 に答える