iOS NSOutputStream第一个符号后分割数据

问题描述:

我们目前正在开发TLS服务器客户端应用程序。为了测试客户端发送内容为“0001”的命令并且服务器发送答案。
客户端通过NSOutputStream的写入方法发送数据。当数据第一次发送时,它完全到达。当我第二次或第三次发送数据时,数据在第一个字节后被分割。服务器首先获得“0”,而其余的则为“001”。我不知道它为什么分裂。

iOS NSOutputStream第一个符号后分割数据

通信的样子:
ServerConnect
发送到服务器:从服务器接收:OK
发送到服务器:0
收到 从服务器错误:
发送到服务器:001
从接收服务器: 错误
发送到服务器:0
接收来自服务器错误:
发送 服务器:001
从服务器接收:错误
ServerDisconnect

我希望有人能帮助我。

- (void)initNetworkCommunication:(NSString*)ns_IP :(UInt32)ui_Port :(BOOL)b_ValidateCertificate 
{ 

    CFReadStreamRef readStream; 
    CFWriteStreamRef writeStream; 

    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)ns_IP, ui_Port, &readStream, &writeStream); 

    inputStream = (__bridge NSInputStream *)readStream; 
    outputStream = (__bridge NSOutputStream *)writeStream; 

    [inputStream setDelegate:(id)self]; 
    [outputStream setDelegate:(id)self]; 

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

    NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys: 
          [NSNumber numberWithBool:b_ValidateCertificate], kCFStreamSSLValidatesCertificateChain, 
          [NSNumber numberWithBool:YES], kCFStreamPropertyShouldCloseNativeSocket, 
          kCFNull,kCFStreamSSLPeerName, 
          kCFStreamSocketSecurityLevelSSLv3, kCFStreamSSLLevel, 
          nil]; 

    CFReadStreamSetProperty((CFReadStreamRef)inputStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings); 
    CFWriteStreamSetProperty((CFWriteStreamRef)outputStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings); 

    [inputStream open]; 
    [outputStream open]; 
} 
- (BOOL) sendData:(NSString*)ns_SendData :(NSUInteger)nui_bufferLength 
{ 
    NSUInteger nui_length = [ns_SendData length]; 
    NSUInteger nui_chunkSize = nui_bufferLength; 
    NSUInteger nui_offset = 0; 
    long l_Result; 

    NSString *ns_response = [NSString stringWithFormat:@"%@", ns_SendData]; 
    NSData *nd_data = [[NSData alloc] initWithData:[ns_response dataUsingEncoding:NSASCIIStringEncoding]]; 

    // a none-ASCII-symbol exists 
    if ([nd_data length] == 0) 
    return FALSE; 

    // split the data 
    do { 
    NSUInteger nui_thisChunkSize = nui_length - nui_offset > nui_chunkSize ? nui_chunkSize : nui_length - nui_offset; 
    NSData* chunk = [NSData dataWithBytesNoCopy:(char *)[nd_data bytes] + nui_offset 
             length:nui_thisChunkSize 
            freeWhenDone:NO]; 
    nui_offset += nui_thisChunkSize; 

    // send data to server 
    l_Result = [outputStream write:[chunk bytes] maxLength:[chunk length]]; 
    NSLog(@"%s - %lu", __PRETTY_FUNCTION__, l_Result); 

    if (l_Result == -1) { 
     NSLog(@"error sending data"); 
     return false; 
    } 

    } while (nui_offset < nui_length); 

    return true; 
} 

的问题通过使用TLS 1.2解决。参见应用技术说明TN2287

const void* keys[] = { kCFStreamSSLValidatesCertificateChain, kCFStreamSSLLevel }; 
    // New CFString values available only on iOS 5: 
    // (if these values are used on versions before iOS 5, then will 
    // default to max TLS 1.0, min SSLv3) 
    // kCFStreamSocketSecurityLevelTLSv1_0SSLv3 configures max TLS 1.0, min SSLv3 
    // (same as default behavior on versions before iOS 5). 
    // kCFStreamSocketSecurityLevelTLSv1_0 configures to use only TLS 1.0. 
    // kCFStreamSocketSecurityLevelTLSv1_1 configures to use only TLS 1.1. 
    // kCFStreamSocketSecurityLevelTLSv1_2 configures to use only TLS 1.2. 
    const void* values[] = { CFSTR("kCFBooleanTrue"), CFSTR("kCFStreamSocketSecurityLevelTLSv1_2") }; 

    CFDictionaryRef sslSettingsDict = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 2, 
                 &kCFTypeDictionaryKeyCallBacks, 
                 &kCFTypeDictionaryValueCallBacks); 

    CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, sslSettingsDict); 
    CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, sslSettingsDict); 
    CFRelease(sslSettingsDict);