iOS NSOutputStream 在第一次签名后拆分数据
iOS NSOutputStream split data after first sign
我们目前正在开发 TLS 服务器客户端应用程序。为了测试客户端发送内容为“0001”的命令,服务器发送一个应答。
客户端通过 NSOutputStream 的写入方法发送数据。第一次发送数据时,它完全到达。当我第二次或第三次发送它时,数据在第一个字节之后被拆分。服务器首先获得“0”,然后获得其余的“001”。我不知道为什么要拆分。
The communication looks like:
ServerConnect
send to server:
0001
receive from server: OK
send to server: 0
receive
from server: error
send to server: 001
receive from server:
error
send to server: 0
receive from server: error
send
to server: 001
receive from server: error
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);
我们目前正在开发 TLS 服务器客户端应用程序。为了测试客户端发送内容为“0001”的命令,服务器发送一个应答。
客户端通过 NSOutputStream 的写入方法发送数据。第一次发送数据时,它完全到达。当我第二次或第三次发送它时,数据在第一个字节之后被拆分。服务器首先获得“0”,然后获得其余的“001”。我不知道为什么要拆分。
The communication looks like:
ServerConnect
send to server: 0001
receive from server: OK
send to server: 0
receive from server: error
send to server: 001
receive from server: error
send to server: 0
receive from server: error
send to server: 001
receive from server: error
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);