gpt4 book ai didi

ios - 如何为iOS中的网络连接测试计算有效负载大小和超时长度?

转载 作者:行者123 更新时间:2023-11-28 23:53:14 25 4
gpt4 key购买 nike

我的应用程序提供了从我们的服务器下载3430个高分辨率图像的选项,每个图像大小为50k-600k字节。

最初的方法是仅下载所有这些文件,但是我们意识到这给了很多NSURLErrorTimedOut错误,导致程序崩溃。现在,我们已经实现了它,以便我们下载所有图像,但一次下载100张图像。

- (void)batchDownloadImagesFromServer:(BOOL)downloadHiResImages
{

[UIApplication sharedApplication].idleTimerDisabled = YES;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

[self generateImageURLList:YES];

[leafletImageLoaderQueue removeAllObjects];
numberOfThumbnailLeft = [uncachedThumbnailArray count];
numberOfHiResImageLeft = [uncachedHiResImageArray count];

NSLog(@"DEBUG: In batchDownloadImagesFromServer numberOfThumbnailLeft %ul , numberOfHiResImageLeft %ul ", numberOfThumbnailLeft, numberOfHiResImageLeft);

numberOfImagesToDownload = numberOfThumbnailLeft;
if (downloadHiResImages)
{
numberOfImagesToDownload += numberOfHiResImageLeft;
}

if (numberTotalToDownload < 0) {
numberTotalToDownload = numberOfHiResImageLeft;
}

int midBatchCt = 0;
// start where we stopped
NSArray *subArray;
NSRange batchRange;
batchRange.location = 0;//uncachedHiResIndex;
NSInteger uncachedNumber = [uncachedHiResImageArray count];
NSLog(@"uncachedHiResIndex and numberTotalToDownload: %d %d", uncachedHiResIndex, numberTotalToDownload);
if (uncachedHiResIndex >= numberTotalToDownload || batchRange.location >= uncachedNumber) {
// we have reached the end of the uncached hires images

NSLog(@" END of download total to download=%ld , uncachedNumber=%ld, # not downloaded is %ld", (long)numberTotalToDownload, uncachedNumber, (long)numberFailedToDownload);
return;
}
if (batchRange.location+100 > uncachedNumber) {
NSInteger imagesUntilEnd = uncachedNumber -1;
batchRange.length = imagesUntilEnd;
NSLog(@"this is uncached number: %d this is uncachedhiresindex:%d and this images until end:%d ", uncachedNumber, uncachedHiResIndex, imagesUntilEnd);

} else {
batchRange.length = 100;
}
NSLog(@" NEW RANGE is from %lul to %lul ", (unsigned long)batchRange.location, batchRange.length);
subArray = [uncachedHiResImageArray subarrayWithRange:batchRange];
if (downloadHiResImages)
{
for ( LeafletURL* aLeafletURL in subArray )
{
LeafletImageLoader* hiResImageLoader = [[LeafletImageLoader alloc] initWithDelegate:self];
[leafletImageLoaderQueue addObject:hiResImageLoader]; // do this before making connection!! //

[hiResImageLoader loadImage:aLeafletURL isThumbnail:NO isBatchDownload:YES];

//// Adding object to array already retains it, so it's safe to release it here. ////
[hiResImageLoader release];

midBatchCt++;
uncachedHiResIndex++;
if (midBatchCt == 10) {
NSLog(@" Waiting for queued images to download...");
NSLog(@" REMOVED from QUEUE %lul , UncachedIndex %lul", numberRemovedFromQueue, uncachedHiResIndex);
break;
}
}
}



if ( [leafletImageLoaderQueue count] == 0 && numberRemovedFromQueue == numberTotalToDownload) {
if([delegate respondsToSelector:@selector(requestDidBatchDownloadImages:)])
{
[delegate requestDidBatchDownloadImages:self];
}
}


}


这解决了我们的大多数问题。但是,即使在开始批量下载之前,我们也要测试网络连接性。我发现一个 low level ping library可以提供准确的往返计时结果。使用来自GBPing的演示代码作为参考,在调用 batchDownloadImagesFromServer之前,我编写了自己的代码来ping服务器。

- (IBAction)preloadAll:(id)sender
{
self.ping = [GBPing new];
self.ping.host = kDefaultDataServer;
self.ping.delegate = self;
self.ping.timeout = 1;
self.ping.pingPeriod = 0.9;

// setup the ping object (this resolves addresses etc)
[self.ping setupWithBlock:^(BOOL success, NSError *error) {
if (success) {
// start pinging
[self.ping startPinging];

// stop it after 5 seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"stop it");
[self.ping stop];
self.ping = nil;
});
} else {
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"Internet Connection"
message:@"Not strong enough internet connection"
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction* OKButton = [UIAlertAction
actionWithTitle:@"Ok"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
[downloadManager batchDownloadImagesFromServer:YES];
}];

[alert addAction:OKButton];
[self presentViewController:alert animated:NO completion:nil];
}

}];
}


我是网络新手。考虑批处理大小和图像大小,如何确定测试的有效负载大小和超时长度?

最佳答案

超时时间是每个请求的时间。这只是网络代码在放弃之前等待答复的时候。长度不应该太短,但是对于大多数系统API来说,超时时间大约是一分钟或更长,可能太长。

另外,请注意,如果连接不良,您仍然会收到超时错误,因此,需要修复导致崩溃的原因。您必须能够从超时中恢复。

您没有提供太多有关崩溃的信息(这是什么崩溃?您得到什么回溯?),但是我可以看到可能发生的三件事:


您是在紧密循环中进行下载的,其中没有@autoreleasepool {}块。这意味着您所有下载的文件数据都累积在RAM中,并耗尽了应用程序的内存限制。确保将自动释放池置于长时间运行的循环中。
您正在主线程上进行这些下载。主线程用于UI和简短操作。如果您的主线程代码执行的操作花费的时间超过几秒钟,则UIApplication将无法处理来自用户的触摸事件(以及其他事件),并且操作系统将其无响应地记录下来。将较长的操作卸载到调度队列上(或使用其他方式将操作从主线程中移出,例如使用异步API)。
您正在向服务器发送大量请求,并且服务器内部的某些DDoS保护功能决定在几分钟内忽略来自您的请求,这是一种自我保护的形式。许多服务器在给定的时间内限制了它们将接受来自客户端的请求数量,或者客户端可能同时具有多少个打开的连接。


我认为通过显示执行实际下载的代码会更好。您无需获取准确的ping定时信息即可下载一堆图像文件。

假定上述可能性中的一种或多种是正确的,我建议您像这样实现您的下载代码:


创建所有需要下载的文件URL的列表。
编写您的代码,以便它按顺序下载这些URL。即在上一个文件完成(或失败并且您决定暂时跳过该文件)之前,不要让它开始下载文件。
使用NSURLSession的支持将单个文件下载到文件夹,不要使用代码获取NSData并自己保存文件。这样,下载完成时无需运行您的应用程序。
如果您的下载被中断,或者在下载中途重启了手机,请确保告诉您是否已经下载了文件。您可以例如为此,可以比较它们的名称(如果它们足够唯一),或者将注释保存到plist中,以使您将下载的文件与文件的来源URL相匹配,或者构成您情况下的识别特征。
启动时,检查是否所有文件都在那里。如果不是,请将丢失的文件放在上面的下载列表中,然后按顺序下载它们,如#2所示。
在开始下载任何内容(包括在先前的下载完成或失败之后下载下一个文件)之前,请使用Apple的SystemConfiguration.framework中的Reachability API进行可达性检查。这将告诉您用户是否已建立连接,以及您是使用WiFi还是使用蜂窝网络(通常,您不希望通过蜂窝网络下载大量文件,大多数蜂窝网络连接都是按流量计费的)。


如果您的图像存储在单独的服务器上,或者它们比较小,并且设置连接的开销比实际下载数据要多,则可以修改代码以一次下载多个图像,但是通常,如果下载的图像数量超过同时从一台服务器获取4张图像,您可能看不到性能提升,因为每增加一个图像只会减少其他图像的可用带宽量。

关于ios - 如何为iOS中的网络连接测试计算有效负载大小和超时长度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51697484/

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