我有一些 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
时,我存储 native 套接字句柄:
NSSocketNativeHandle *socketHandle = [[outputStream propertyForKey:(NSString *)kCFStreamPropertySocketNativeHandle] bytes];
我根据需要处理 NSStreamEventHasBytesAvailable
和 NSStreamEventHasSpaceAvailable
事件。然后从存储的套接字句柄创建两个新流,并设置 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
事件在两个新流上都被调用,但是 NSStreamEventHasBytesAvailable
和 NSStreamEventHasSpaceAvailable
事件从未被引发。知道我做错了什么吗?
最佳答案
看来我的问题有两个方面。
当通过
CFStreamCreatePairWithSocketToHost
创建连接时,kCFStreamPropertyShouldCloseNativeSocket
属性自动设置为 TRUE。它应该是假的。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];
我没有正确设置 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];
关于cocoa - 通过同一个套接字进行安全和不安全的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4615921/