2011-01-06 39 views
0

我有一些Python代码,我正试图将其转换为Obj-C/Cocoa。它需要网络连接;初始化字符串以明文形式发送,然后连接被保护。 基本上,它的工作原理是这样的:安全和不安全的连接通过相同的套接字

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.connect((host,port)) 
sock.send(...) 
sock.recv(...) 
sslSock = ssl.wrap_socket(sock) 
sslSock.send(...) 
sslSock.recv(...) 

到目前为止,我有以下。首先,我创建套接字连接和R/W流:

CFReadStreamRef readStream; 
CFWriteStreamRef writeStream; 

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)HOST, PORT, &readStream, &writeStream); 

inputStream = (NSInputStream *)readStream; 
[inputStream setDelegate:self]; 
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

outputStream = (NSOutputStream *)writeStream; 
[outputStream setDelegate:self]; 
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

[inputStream open]; 
[outputStream open]; 

NSStreamEventOpenCompleted是送的,我保存了原始套接字句柄:

NSSocketNativeHandle *socketHandle = [[outputStream propertyForKey:(NSString *)kCFStreamPropertySocketNativeHandle] bytes]; 

我处理NSStreamEventHasBytesAvailableNSStreamEventHasSpaceAvailable事件酌情。然后从存储的套接字句柄中创建两个新的流,并设置SSL属性:

[inputStream close]; 
[outputStream close]; 
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
[outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

CFStreamCreatePairWithSocket(kCFAllocatorDefault, *socketHandle, &readStream, &writeStream); 

inputStream = (NSInputStream *)readStream; 
[inputStream setDelegate:self]; 
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
[inputStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey]; 

outputStream = (NSOutputStream *)writeStream; 
[outputStream setDelegate:self]; 
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
[outputStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey]; 

[inputStream open]; 
[outputStream open]; 

这就是我得到的。两个新的流都会调用NSStreamEventOpenCompleted事件,但不会引发NSStreamEventHasBytesAvailableNSStreamEventHasSpaceAvailable事件。任何想法我做错了什么?

回答

1

看起来像我的问题是双重的。

  1. 当创建经由CFStreamCreatePairWithSocketToHost的连接时,kCFStreamPropertyShouldCloseNativeSocket属性被自动设置为TRUE。它应该是FALSE。

    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)HOST, PORT, &readStream, &writeStream); 
    inputStream = (NSInputStream *)readStream; 
    [inputStream setDelegate:self]; 
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [inputStream setProperty:(id)kCFBooleanFalse forKey:(NSString *)kCFStreamPropertyShouldCloseNativeSocket]; 
    
  2. 我没有正确设置SSL。

    NSMutableDictionary *sslSettings = [[NSMutableDictionary alloc] init]; 
    [sslSettings setObject:NSStreamSocketSecurityLevelNegotiatedSSL forKey:(NSString *)kCFStreamSSLLevel]; 
    [sslSettings setObject:(id)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsAnyRoot]; 
    [sslSettings setObject:HOST forKey:(NSString *)kCFStreamSSLPeerName]; 
    [inputStream setProperty:sslSettings forKey:(NSString *)kCFStreamPropertySSLSettings]; 
    [inputStream open]; 
    
+0

你好,对不起重提老问题,但我有同样的问题。我需要使用套接字来做些事情,然后将其升级到安全状态。我已经尝试过您描述的方法,但我仍然没有收到NSStreamEventHasBytesAvailable事件。我甚至试图在没有任何安全升级的情况下重新创建流,但它仍然是一样的。我在iPad上运行iOS 6。你的代码是否仍然有效?或者你可能做了一些改进? – user1264176 2013-09-18 15:35:32