

GCDAsyncSocketというライブラリを用いてソケット通信を行っていたのですが、  
IPv6 only Networkでのデバッグで

[code]

    lost connect Error Domain=NSPOSIXErrorDomain Code=51 "Network is unreachable" UserInfo={NSLocalizedDescription=Network is unreachable, NSLocalizedFailureReason=Error in connect() function}
    
[/code]

というエラーが出てしまいどうにもいかなくなってしまったため、  
NSStreamでの実装を行っているのですが、データの受信でデータが欠けるという事態に対処ができなくご教示いただけたらと思っております。

GCDAsyncSocketであれば、readDataToLengthで指定した長さのソケットを読み込むことが出来、それにより受け取るソケットのサイズを把握することができたのですが、NSStreamではそのような実装は可能なのでしょうか？

NSStreamEventHasBytesAvailableでは以下のようにしてNSDataを取得しています

[code]

    uint8_t buffer[4096];
    unsigned int len = 0;
    while ([InputStream hasBytesAvailable])
    {
        [InputStream getBuffer:&buffer length:&len];
        len = [InputStream read:buffer maxLength:sizeof(buffer)];
        if (len > 0){
    
            NSData *data = [NSData dataWithBytes:buffer length:len];
    
        }
    }
    
[/code]

よろしくお願いいたします。


CC BY-SA 3.0
2016-02-07T21:15:05.947
21821
2016-09-20T01:50:48.417
12972
question
ios objective-c socket
NSStreamを用いたソケット通信でデータの長さを指定した受信動作をしたい


2行目と5行目が間違っていると思います。  
まず、5行目は不要で、いきなり

[code]

    - (NSUInteger) read:(nonnull uint8_t *)buffer maxLength:(NSUInteger)length;
    
[/code]

メソッドでデータを読み出します。その際にlenのポインターを渡しているのでlenのアドレスである途轍もなく大きいバイト数まで読み出そうとしているのが原因では無いかと思います。  
以下は実際に動いている、セパレーターキャラクターが来るまで1バイトずつ読み出すコードです。

[code]

    uint8_t oneByte;
    NSInteger actuallyRead = 0;
    BOOL repeat = YES;
    do {    // read from stream
        actuallyRead = [readStream read:&oneByte maxLength:1U];
            // check data
        switch (actuallyRead) {
            case 1:     // success normaly one byte.
                if (oneByte == '\0')
                    repeat = NO;
                else
                    CFDataAppendBytes(recievedData, &oneByte, actuallyRead);
                break;
            case 0:
                return;
                break;
            default:
                NSLog(@"Error at reading stream %@ : %@", NSStringFromSelector(_cmd), [self class]);
                NSLog(@"Stream Status : %lu", [readStream streamStatus]);
                NSLog(@"Stream Error : %@", [readStream streamError]);
                return;
                break;
        }// end switch
    } while (repeat);
    
[/code]


CC BY-SA 3.0
2016-03-12T03:10:30.970
23041
2016-03-12T03:10:30.970
14745
21821
answer