Cocoa 从 FTP 连接读取 NSInputStream

发布于 2024-08-27 10:38:59 字数 2703 浏览 2 评论 0原文

我(显然)设法建立了 ftp 连接,但无法从中读取任何内容,并且有充分的理由:直到连接超时我才达到读数。

这是我的代码:

header:

NSInputStream *iStream;
NSOutputStream *oStream;

implementation:

        NSHost *host = [NSHost hostWithAddress:@"127.0.0.1"];
        [iStream open]; // SOLUTION changes
        [NSStream getStreamsToHost:host port:3333 inputStream:&iStream outputStream:&oStream];

        NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithCapacity:1];
        [settings setObject:(NSString *)NSStreamSocketSecurityLevelTLSv1 forKey:(NSString *)kCFStreamSSLLevel];
        [settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsAnyRoot];
        [settings setObject:@"127.0.0.1" forKey:(NSString *)kCFStreamSSLPeerName];

        /*[iStream retain];   
        [iStream setDelegate:self];
        [iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        CFReadStreamSetProperty((CFReadStreamRef)iStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
        [iStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];*/
        //[iStream open]; SOLUTION changes: moved up

对于事件处理,我使用它,基于 http://www. cocoadev.com/index.pl?NSStream

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
    if (aStream == iStream) {
        [self handleInputStreamEvent:eventCode];
    } else if (aStream == oStream) {
        [self handleOutputStreamEvent:eventCode];
    }
}
- (void)handleInputStreamEvent:(NSStreamEvent)eventCode
{
    switch (eventCode) {
    // SOLUTION changes: new inputstream handler
    case NSStreamEventHasBytesAvailable:
        if(!_data) {
            _data = [[NSMutableData data] retain];
        }
        uint8_t buf[1024];
        unsigned int len = 0;
        len = [(NSInputStream *)iStream read:buf maxLength:1024];
        if(len) {
            [_data appendBytes:(const void *)buf length:len];
            [bytesRead setIntValue:[bytesRead intValue]+len];
        }
        [self readBytes];
        break;
    case NSStreamEventOpenCompleted:
        NSLog(@"NSStreamEventOpenCompleted");
        break;
    case NSStreamEventEndEncountered:
        NSLog(@"NSStreamEventEndEncountered");
        break;
    case NSStreamEventErrorOccurred:
        NSLog(@"An error occurred on the input stream.");
        break;
    }
}

我在这篇文章中省略了 oStream 设置,以保持最小化。

我还没有向 FTP 发送切换到 ssl 的请求。

非常感谢任何帮助,因为我发现 Xcode 的调试非常糟糕(失败的步骤没有异常或错误消息)。

  • 查克

I (apparently) manage to make a ftp connection, but fail to read anything from it, and with good cause: I don't reach the reading until the connection has timed out.

Here's my code:

header:

NSInputStream *iStream;
NSOutputStream *oStream;

implementation:

        NSHost *host = [NSHost hostWithAddress:@"127.0.0.1"];
        [iStream open]; // SOLUTION changes
        [NSStream getStreamsToHost:host port:3333 inputStream:&iStream outputStream:&oStream];

        NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithCapacity:1];
        [settings setObject:(NSString *)NSStreamSocketSecurityLevelTLSv1 forKey:(NSString *)kCFStreamSSLLevel];
        [settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsAnyRoot];
        [settings setObject:@"127.0.0.1" forKey:(NSString *)kCFStreamSSLPeerName];

        /*[iStream retain];   
        [iStream setDelegate:self];
        [iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        CFReadStreamSetProperty((CFReadStreamRef)iStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
        [iStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];*/
        //[iStream open]; SOLUTION changes: moved up

For eventhandling I use this, based on http://www.cocoadev.com/index.pl?NSStream:

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
    if (aStream == iStream) {
        [self handleInputStreamEvent:eventCode];
    } else if (aStream == oStream) {
        [self handleOutputStreamEvent:eventCode];
    }
}
- (void)handleInputStreamEvent:(NSStreamEvent)eventCode
{
    switch (eventCode) {
    // SOLUTION changes: new inputstream handler
    case NSStreamEventHasBytesAvailable:
        if(!_data) {
            _data = [[NSMutableData data] retain];
        }
        uint8_t buf[1024];
        unsigned int len = 0;
        len = [(NSInputStream *)iStream read:buf maxLength:1024];
        if(len) {
            [_data appendBytes:(const void *)buf length:len];
            [bytesRead setIntValue:[bytesRead intValue]+len];
        }
        [self readBytes];
        break;
    case NSStreamEventOpenCompleted:
        NSLog(@"NSStreamEventOpenCompleted");
        break;
    case NSStreamEventEndEncountered:
        NSLog(@"NSStreamEventEndEncountered");
        break;
    case NSStreamEventErrorOccurred:
        NSLog(@"An error occurred on the input stream.");
        break;
    }
}

I've left out oStream setup from this post to keep it minimal.

I have not sent a request to the FTP to switch to ssl yet.

Any help is greatly appreciated as I find Xcode quite horrible for debugging (no exception or error msg on failed steps what so ever).

  • Chuck

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

天冷不及心凉 2024-09-03 10:38:59

请参阅 轮询与运行循环调度。请注意关键字

此外,我认为责怪 Xcode 的调试功能是不公平的。 Xcode 是 IDE,非常适合调试。当出现问题时,API 应该引发异常(或返回 nil),而且我在 objc_exception_throw()-[NSException raise] 上设置断点从来没有遇到过问题code> 在调试会话期间捕获异常。

另一点需要考虑:你没有任何保护代码。这意味着您忽略了无法成功建立连接的可能性。错误检测的一部分是确保您自己的代码能够检测并处理故障,尤其是在涉及网络通信的情况下。

See Polling Versus Run-Loop Scheduling. Note the key word versus.

Further, I don't think it's fair to blame Xcode's debugging capabilities. Xcode is the IDE and works quite well for debugging. The API is what should be raising exceptions (or returning nil) when something goes wrong and I've never had a problem setting a breakpoint on objc_exception_throw() or -[NSException raise] to catch exceptions during my debugging sessions.

Another point to consider: You have no guard code whatsoever. This means you're ignoring the possibility that a connection might not be established successfully. Part of error detection is making sure your own code detects and handles failures, especially where network communications are involved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文