@Rob Napier @Eric Nelson Come già menzionato: "NSURLConnection è abbastanza intelligente da gestire ciò per te utilizzando HTTP/1.1 e riutilizzando le connessioni esistenti". Tuttavia, non riesco a trovare una descrizione del genere in nessun documento Apple.
Per fare cosa chiara, ho scrivere del codice per testarlo:
- (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];
}
E poi, comincio Wireshark per catturare i pacchetti sul server (192.168.1.xxx), utilizzando "(tcp.flags .syn == 1) || (tcp.flags == 0x0010 & & tcp.seq == 1 & & tcp.ack == 1) "per filtrare il tremolio della mano a tre vie tcp. Sfortunatamente, posso vedere il tremolio della mano a 3 vie per ogni chiamata di "sendOneRequest". Il che significa che NSURLConnection sembra non riutilizzare le connessioni esistenti. Qualcuno può segnalare cosa c'è di sbagliato nel mio codice e come inviare più richieste tramite una connessione socket tramite NSURLConnection?
Ho anche provato modo sincrono di inviare richiesta:
-(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];
}
e il risultato è lo stesso.
======= UPDATE ============================
Infine, ho trovato la ragione perché il mio test è diverso da Rob e Eric dicono. In breve, Rob e Eric hanno ragione. E NSURLConnection usa "keep-alive" come predefinito per l'utilizzo di HTTP/1.1 e riutilizza la connessione socket esistente, ma solo per un intervallo di tempo relativamente piccolo.
Tuttavia, NSURLConnection presenta alcuni problemi per "codifica di trasferimento chunked" (cioè senza lunghezza del contenuto).
Nel mio test, il lato server invia una risposta senza dati di lunghezza del contenuto e di risposta, ed è una risposta frammentata e NSURLConnection chiuderà la connessione, quindi si verifica un tremolio della mano a 3 vie per ogni post http.
Ho modificato il mio codice server, impostato la lunghezza della risposta come 0 e il comportamento è corretto.
if (! Connection) connection = [[NSURLConnection alloc] initWithRequest: request delegate: self startImmediately: NO]; [avvio connessione]; Questo non funziona restituisce "EXC_BAD_ACCESS". Ho cercato forum per questo e non c'è risposta. Sembra che "start" sia necessario per usare un altro modo. – slatvick
È una stranezza di questo metodo di inizializzazione che è necessario pianificare la connessione su un runloop prima di avviarlo. –