0

3G 経由でサーバーと通信する iOS アプリケーションを実行しています。このサーバーは、HTTP リクエストを受信して​​処理します。最近、異なる 3g プロバイダーを使用してサーバーと通信すると、結果がかなり異なることに気付き始めました。

たとえば、あるケースでは、次の方法を使用して zip ファイルをアップロードしようとしています。

+ (void) UploadZipImages:(NSString*)zipFilePath delegate:(UIViewController *)_delegate{

isLastUploadLocal = false;

NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:@"yyyyMMddhhmmss"];
NSString *dateString = [dateFormatter stringFromDate:date];

// Dictionary that holds post parameters. You can set your post parameters that your server accepts or programmed to accept.
NSString *title = [NSString stringWithFormat:@"%@.zip", dateString];

// the boundary string : a random string, that will not repeat in post data, to separate post data fields.
NSString *BoundaryConstant = @"----WebKitFormBoundary5FyPE45e6sSDdGnYP";

// string constant for the post parameter 'file'. My server uses this name: `file`. Your's may differ
NSString* FileParamConstant = @"file";

// the server url to which the image (or the media) is uploaded. Use your server url here
NSURL* requestURL = [NSURL URLWithString:@"http://*************"];

NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
[_params setObject:[NSString stringWithFormat:@"%@",title] forKey:@"title"];
NSMutableDictionary* _params2 = [[NSMutableDictionary alloc] init];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:1200];
[request setAllowsCellularAccess:YES];
[request setHTTPMethod:@"POST"];
[request setNetworkServiceType:NSURLNetworkServiceTypeDefault];

// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", BoundaryConstant];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];

NSMutableData *body = [NSMutableData data];

// add params (all params are strings)
for (NSString *param in _params) {
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"%@\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}

NSError *myError = nil;

NSData *imageData = [NSData dataWithContentsOfFile:zipFilePath];
if (imageData) {
    NSLog(@"Temos imagem!!!!");
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"movie.zip\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:imageData];
    [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}else{
    NSLog(@"There was an error %@", myError);
}

// setting the body of the post to the reqeust
[request setHTTPBody:body];

// set the content-length
NSString *postLength = [NSString stringWithFormat:@"%d", [body length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];


// set URL
[request setURL:requestURL];

[[NSURLConnection alloc] initWithRequest:request delegate:_delegate]; 

}

これは、特定の 3G インターネット プロバイダーを使用すると正常に動作します (かなり高速です) が、別のオペレーターの場合、タイムアウト間隔に達するまで、要求の処理が永久に開始されます... この問題を引き起こす可能性のある 3G ネットワーク プロバイダー間の違いは何ですか?

ありがとうございました。

4

1 に答える 1

0

multipart/form-data メッセージには 2 つの問題があります。

  1. 画像データに厳密に属する画像データの後に CRLF を追加しています。受信者は混乱する可能性があります (おそらくそうなるでしょう)。サーバーがCRLFで終わらないタイプのテキストの本文部分で混乱しない限り、それを省略してください。

  2. 最後の部分 (画像データ) の後に、終了境界区切り文字が必要です。追加する必要があります

    [body appendData:[[NSString stringWithFormat:@"--%@--", BoundaryConstant]
                                 dataUsingEncoding:NSUTF8StringEncoding]];
    

ノート:

  1. また、最初の境界区切り文字が CRLF で始まることを確認する必要があります (これは、NSURLConnection がメッセージ ヘッダーの後に CRLF を追加するため、おそらく既に確認されています)。ただし、追加の最初の CRLF は、「プロローグ」として扱われますが、意味的な意味はありません。

  2. 厳密には、終了デリミタの後に CRLF は必要ありませんが、意味的な意味を持たない「エピローグ」として扱われるため、問題はありません。

于 2013-10-04T17:11:31.107 に答える