我每隔5秒与服务器异步连接。 URL是相同的,但每次更改POST主体。现在我每次都从头开始创建NSURL,NSURLRequest和NSURLConnection。
我认为设置连接一次更有效,只需进一步使用。 我是新手,不确定是否可能。没有可变的NSURLConnection,但可能需要创建NSURLConnection,如:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
并更改NSMutableURLRequest POST数据以向服务器发送另一个请求。 哪条路是对的?
答案 0 :(得分:10)
我认为您关注的是创建HTTP连接的开销。 NSURLConnection非常智能,可以使用HTTP / 1.1并重用现有连接来处理此问题。它上次检查时不使用流水线操作,但出于您的目的,连接重用应该足够了。我鼓励你在这上面放一个网络嗅探器,并确保它按照你的意愿工作。
创建对象本身的成本是每5秒一次的微不足道的成本,你不应该尝试优化它(当然你应该重用NSURL)。这是开放与服务器的连接,这是昂贵的,尤其是在iPhone上。
如果您发现自己确实需要流水线操作,那么很遗憾,您必须自己动手。我听说CFHTTPStream可以做到,但我没有看到很多证据。 CocoaAsyncSocket是低级访问套接字的最佳选择,无需编写低级代码。
由于单元网络上的延迟可能非常糟糕,因此您的连接可能需要超过5秒才能完成。确保在开始下一个连接之前完成一个连接,或者您将开始建立越来越多的开放连接。
答案 1 :(得分:6)
为了澄清事情,NSURLConnection将重用现有的套接字,但仅限于相对较短的时间范围(12秒)。如果您发送请求,请返回响应,并在12秒内发送第二个请求将在同一个套接字上发出的后续请求。否则,客户端将关闭套接字。已向Apple提交了一个错误,以增加此计时器或使其可配置。
答案 2 :(得分:3)
为了清楚起见,我写了一些代码来测试它:
- (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];