NSURLConnection运行多次

时间:2009-05-20 08:25:57

标签: iphone nsurlconnection

我每隔5秒与服务器异步连接。 URL是相同的,但每次更改POST主体。现在我每次都从头开始创建NSURL,NSURLRequest和NSURLConnection。

我认为设置连接一次更有效,只需进一步使用。 我是新手,不确定是否可能。没有可变的NSURLConnection,但可能需要创建NSURLConnection,如:

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

并更改NSMutableURLRequest POST数据以向服务器发送另一个请求。 哪条路是对的?

4 个答案:

答案 0 :(得分:10)

我认为您关注的是创建HTTP连接的开销。 NSURLConnection非常智能,可以使用HTTP / 1.1并重用现有连接来处理此问题。它上次检查时不使用流水线操作,但出于您的目的,连接重用应该足够了。我鼓励你在这上面放一个网络嗅探器,并确保它按照你的意愿工作。

创建对象本身的成本是每5秒一次的微不足道的成本,你不应该尝试优化它(当然你应该重用NSURL)。这是开放与服务器的连接,这是昂贵的,尤其是在iPhone上。

如果您发现自己确实需要流水线操作,那么很遗憾,您必须自己动手。我听说CFHTTPStream可以做到,但我没有看到很多证据。 CocoaAsyncSocket是低级访问套接字的最佳选择,无需编写低级代码。

由于单元网络上的延迟可能非常糟糕,因此您的连接可能需要超过5秒才能完成。确保在开始下一个连接之前完成一个连接,或者您将开始建立越来越多的开放连接。

答案 1 :(得分:6)

为了澄清事情,NSURLConnection将重用现有的套接字,但仅限于相对较短的时间范围(12秒)。如果您发送请求,请返回响应,并在12秒内发送第二个请求将在同一个套接字上发出的后续请求。否则,客户端将关闭套接字。已向Apple提交了一个错误,以增加此计时器或使其可配置。

答案 2 :(得分:3)

@Rob Napier @Eric Nelson 正如您所提到的:“NSURLConnection非常智能,可以使用HTTP / 1.1并重用现有连接来处理此问题”。 但是,我在Apple的任何文档中都找不到这样的描述。

为了清楚起见,我写了一些代码来测试它:

- (IBAction)onClickSend:(id)sender {
    [self sendOneRequest];
}

-(void)sendOneRequest {

    NSURL *url = [NSURL URLWithString:@"http://192.168.1.100:1234"];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request addValue:[Base64 encodeFromString:kValueVersion] forHTTPHeaderField:kKeyVersion];
    [request addValue:[Base64 encodeFromString:kValueDataTypeCmd] forHTTPHeaderField:kKeyDataType];
    [request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyCmdName];
    [request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyDeviceName];
    [request addValue:[Base64 encodeFromString:@"xxdafadfadfa"] forHTTPHeaderField:kKeyDTLCookies];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];
}

然后,我启动wireshark来捕获服务器上的包(192.168.1.xxx),使用“(tcp.flags.syn == 1)||(tcp.flags == 0x0010&& tcp。 seq == 1&& tcp.ack == 1)“过滤tcp 3-way握手。不幸的是,我可以看到每次调用“sendOneRequest”时的三向握手。这意味着,NSURLConnection似乎没有重用现有的连接。有人可以指出我的代码中有什么问题以及如何通过NSURLConnection通过一个套接字连接发送多个请求吗?

我也尝试过同步方式发送请求:

-(void)sendOneRequest {
    NSURL *url = [NSURL URLWithString:@"http://192.168.1.100:1234"];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request addValue:[Base64 encodeFromString:kValueVersion] forHTTPHeaderField:kKeyVersion];
    [request addValue:[Base64 encodeFromString:kValueDataTypeCmd] forHTTPHeaderField:kKeyDataType];
    [request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyCmdName];
    [request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyDeviceName];
    [request addValue:[Base64 encodeFromString:@"xxdafadfadfa"] forHTTPHeaderField:kKeyDTLCookies];

    [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

    sleep(1);

    [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

    sleep(1);

    [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

}

结果是一样的。

======= UPDATE ============================

最后,我找到了我的测试与Rob和Eric说的不同的原因。 简而言之,Rob和Eric是正确的。并且NSURLConnection使用“keep-alive”作为默认使用HTTP / 1.1并重用现有套接字连接,但仅限于相对较短的时间范围。

然而,NSURLConnection在“分块传输编码”(即没有内容长度)方面存在一些问题。

在我的测试中,服务器端发送没有内容长度和响应数据的响应,并且它是分块响应,NSURLConnection将关闭连接,因此每个http帖子都会发生3路握手。

我更改了服务器代码,将响应长度设置为0,行为正确。

答案 3 :(得分:0)

创建一个返回请求并执行

的方法
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:[self requestMethod] delegate:self];