gpt4 book ai didi

iOS NSStream FTP 在闲置 5 分钟后没有响应

转载 作者:可可西里 更新时间:2023-11-01 06:06:40 25 4
gpt4 key购买 nike

我正在使用适用于 iOS 的 FTP 库 ( nkreipke/FTPManager )。它很好用。我可以下载目录列表、上传图片等。问题是,如果您让应用程序打开大约 5 分钟什么都不做,然后您尝试下载或上传,则什么也不会发生。

我一直在调试它,发现 NSStreamDelegate 方法 - (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent 在短时间之后永远不会被调用不活跃。

代码如下:

- (NSArray*) _contentsOfServer:(FMServer*)server {
BOOL success = YES;

action = _FMCurrentActionContentsOfServer;

fileSize = 0;

self.directoryListingData = [[NSMutableData alloc] init];

NSURL* dest = [server.destination ftpURLForPort:server.port];
And(success, (dest != nil));
Check(success);

if (![dest.absoluteString hasSuffix:@"/"]) {
//if the url does not end with an '/' the method fails.
//no problem, we can fix this.
dest = [NSURL URLWithString:[NSString stringWithFormat:@"%@/",dest.absoluteString]];
}

CFReadStreamRef readStream = CFReadStreamCreateWithFTPURL(NULL, (__bridge CFURLRef)dest);
And(success, (readStream != NULL));
if (!success) return nil;
self.serverReadStream = (__bridge_transfer NSInputStream*) readStream;

And(success, [self.serverReadStream setProperty:server.username forKey:(id)kCFStreamPropertyFTPUserName]);
And(success, [self.serverReadStream setProperty:server.password forKey:(id)kCFStreamPropertyFTPPassword]);
if (!success) return nil;

self.bufferOffset = 0;
self.bufferLimit = 0;

currentRunLoop = CFRunLoopGetCurrent();

self.serverReadStream.delegate = self;
[self.serverReadStream open];
[self.serverReadStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

CFRunLoopRun(); //<- Hangs here.

And(success, streamSuccess);
if (!success) return nil;

NSArray* directoryContents = [self _createListingArrayFromDirectoryListingData:self.directoryListingData];
self.directoryListingData = nil;

return directoryContents;

serverReadStream 是一个 NSInputStream 对象。

当 Action 结束时:

if (self.serverReadStream) {
[self.serverReadStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
CFRunLoopStop(CFRunLoopGetCurrent());
self.serverReadStream.delegate = nil;
[self.serverReadStream close];
self.serverReadStream = nil;
}

此代码位于 FTPManager.m。我一直在互联网上寻找答案,但找不到任何答案。我不知道为什么 NSStreamDelegate 方法在经常使用时会被调用,但在一段时间不活动后,它不会被调用。

如果有人能帮助我就好了。

谢谢。

最佳答案

我在我的 iPad 应用程序中使用相同的库,当我试图在恢复我的应用程序时刷新 FTP 服务器内容时,我被困在同一个 CFRunLoopRun() 调用中。

我必须对 FTPManager 代码做两处更改。

首先,我改变了顺序

[self.serverReadStream open];
[self.serverReadStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[self.serverReadStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.serverReadStream open];

原因是流无法打开。在打开调用期间引发错误事件,但如果流未安排到运行循环,我们将永远不会收到错误事件。因此在打开之前调度将使我们能够获取错误事件。

在我的案例中需要进行的另一项更改是禁用持久连接。似乎在设备的挂起/恢复周期之后,流使用的内部套接字变得陈旧并且在尝试访问它时总是返回错误。

在流配置中添加以下行解决了我这边的问题:

[self.serverReadStream setProperty: (id) kCFBooleanFalse forKey: (id) kCFStreamPropertyFTPAttemptPersistentConnection];

希望这对您有所帮助。

关于iOS NSStream FTP 在闲置 5 分钟后没有响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27303066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com