@ Роб Нейпир @ Эрик Нельсон
Как вы упомянули: «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 трехстороннего дрожания рук. К сожалению, я вижу трёхстороннее дрожание рук для каждого вызова «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 ============================
Наконец, я нашел причину, по которой мой тест отличается от того, что говорят Роб и Эрик.
Короче говоря, Роб и Эрик правы. А NSURLConnection по умолчанию использует «keep-alive» для использования HTTP / 1.1 и повторно использует существующее сокетное соединение, но только в течение относительно небольшого периода времени.
Тем не менее, NSURLConnection имеет некоторые проблемы для «кусочного кодирования передачи» (т. Е. Без длины контента).
В моем тесте серверная сторона отправляет ответ без длины содержимого и данных ответа, а ответ по частям и NSURLConnection закрывает соединение, таким образом, для каждого сообщения http происходит трехстороннее рукопожатие.
Я изменил свой серверный код, установил длину ответа равной 0, и поведение верное.