NSURLConnection运行多次
我每5秒钟与服务器异步连接。 URL是相同的,但POST body每次都会更改。 现在我每次都从头开始创建NSURL,NSURLRequest和NSURLConnection。
我认为设置一次连接并进一步使用该连接会更有效。 我是新手,不确定是否可能。 没有可变的NSURLConnection,但是可能需要创建NSURLConnection:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
并更改NSMutableURLRequest POST数据以发送另一个请求到服务器。 哪种方式是对的?
我假设你关心的是创建HTTP连接的开销。 NSURLConnection足够聪明,可以使用HTTP / 1.1和重用现有连接来处理这个问题。 它没有使用流水线上次我检查,但为了您的目的,连接重用应该是足够的。 我鼓励你把网络嗅探器放在这个上面,并确保它能够按照你的要求工作。
创建对象本身的成本在每5秒一次的次序上是微不足道的,你不应该试图优化它(尽管你当然应该重用NSURL)。 这是开放的连接到服务器是昂贵的,特别是在iPhone上。
如果你发现你真的需要流水线,你不幸的将不得不推出自己的。 我听说CFHTTPStream可以做到,但我没有看到很多这方面的证据。 CocoaAsyncSocket是低级别访问套接字的最佳选择,无需编写低级代码。
由于单元网络上的延迟可能非常糟糕,因此您的连接可能需要超过5秒才能完成。 确保在开始下一个连接之前完成一个连接,否则您将开始建立更多且更开放的连接。
为了澄清事情,NSURLConnection将重用现有的套接字,但仅适用于相对较小的时间段(12秒)。 如果你发送一个请求,取回一个响应,然后在12秒内发送一个后续请求,第二个请求将在同一个套接字上发出。 否则套接字将被客户端关闭。 苹果公司已经提出了一个错误来增加这个定时器或使其可配置。
@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路手摇。 不幸的是,我可以看到每个“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说不同的原因。 总之,罗布和埃里克是正确的。 NSURLConnection使用“keep-alive”作为使用HTTP / 1.1的默认值,并重用现有的套接字连接,但仅限于相对较小的时间范围。
但是,NSURLConnection在“分块传输编码”(即没有内容长度)方面存在一些问题。
在我的测试中,服务器端发送没有内容长度和响应数据的响应,并且它是分块响应,并且NSURLConnection将关闭连接,因此每个http文章都会发生3次握手。
我更改了我的服务器代码,将响应的长度设置为0,并且行为正确。
链接地址: http://www.djcxy.com/p/30579.html