Al momento sei offline in attesa che la connessione Internet venga ristabilita

Problemi di progettazione - l'invio di segmenti di dati di piccole dimensioni su TCP con Winsock

IMPORTANTE: il presente articolo è stato tradotto tramite un software di traduzione automatica di Microsoft ed eventualmente revisionato dalla community Microsoft tramite la tecnologia CTF (Community Translation Framework) o da un traduttore professionista. Microsoft offre articoli tradotti manualmente e altri tradotti automaticamente e rivisti dalla community con l’obiettivo di consentire all'utente di accedere a tutti gli articoli della Knowledge Base nella propria lingua. Tuttavia, un articolo tradotto automaticamente, anche se rivisto dalla community, non sempre è perfetto. Potrebbe contenere errori di vocabolario, di sintassi o di grammatica. Microsoft declina ogni responsabilità per imprecisioni, errori o danni causati da una traduzione sbagliata o dal relativo utilizzo da parte dei clienti. Microsoft aggiorna frequentemente il software e gli strumenti di traduzione automatica per continuare a migliorare la qualità della traduzione.

Clicca qui per visualizzare la versione originale in inglese dell’articolo: 214397
Sommario
Quando è necessario inviare pacchetti di dati di piccole dimensioni su TCP, la progettazione dell'applicazione Winsock è particolarmente importante. Una progettazione che non prendono in considerazione l'interazione di ritardata di riconoscimento, l'algoritmo Nagle e Winsock buffering può notevolmente influire sulle prestazioni. In questo articolo vengono illustrati questi problemi, utilizzando un paio di studi di casi e deriva una serie di raccomandazioni per l'invio di pacchetti di dati di piccole dimensioni in modo efficiente da un'applicazione Winsock.
Informazioni

Sfondo

Quando uno stack TCP Microsoft riceve un pacchetto di dati, un timer di ritardo di 200 ms si spegne. Quando alla fine viene inviato un ACK, il timer di ritardo viene reimpostato e avvia un altro ritardo di 200 ms quando viene ricevuto il pacchetto di dati successivo.Per aumentare l'efficienza in Internet e le applicazioni intranet, stack Microsoft TCP/IP utilizza i seguenti criteri per decidere quando inviare un ACK sui pacchetti di dati ricevuti:
  • Se si riceve il pacchetto di dati secondo prima che scada il timer di ritardo, viene inviato l'ACK.
  • Se sono presenti dati da inviare nella stessa direzione, come l'ACK prima riceve il secondo pacchetto di dati e la scadenza del timer di ritardo, l'ACK piggyback con il segmento di dati e inviati immediatamente.
  • Alla scadenza del timer di ritardo, viene inviato l'ACK.
Per evitare i pacchetti di dati di piccole dimensioni congest rete, stack Microsoft TCP/IP consente l'algoritmo Nagle per impostazione predefinita, che assegna un buffer di dati di piccole dimensioni da più chiamate di invio e ritardi l'invio che fino a quando non viene inviato un ACK per il pacchetto di dati precedente viene ricevuto dall'host remoto. Di seguito sono riportati due eccezioni all'algoritmo Nagle.
  • Se lo stack è fuse un buffer di dati più grande rispetto l'unità massima di trasmissione (MTU), un pacchetto di dimensioni viene inviato immediatamente senza attendere l'ACK dall'host remoto. Su una rete Ethernet, il valore MTU per TCP/IP è 1460 byte.
  • L'opzione di socket TCP_NODELAY viene applicata per disabilitare l'algoritmo Nagle in modo che i pacchetti di dati di piccole dimensioni vengono recapitati all'host remoto senza indugio.
Per ottimizzare le prestazioni a livello di applicazione, i buffer di dati dall'applicazione Winsock copie inviano le chiamate a un buffer del kernel di Winsock. Quindi, lo stack utilizza le regole euristiche (ad esempio, l'algoritmo Nagle) per determinare quando effettivamente installare il pacchetto in transito. È possibile modificare la quantità di Winsock kernel buffer allocati al socket utilizzando l'opzione SO_SNDBUF (è 8 KB per impostazione predefinita). Se necessario, Winsock può memorizzare nel buffer in modo significativo oltre la dimensione del buffer di SO_SNDBUF. Nella maggior parte dei casi, il completamento dell'invio dell'applicazione indica solo il buffer di dati in un'applicazione invia la chiamata viene copiato nel buffer del kernel Winsock e non indica che i dati ha raggiunto il supporto di rete. L'unica eccezione è quando si disabilita il buffering Winsock impostando SO_SNDBUF su 0.

Winsock utilizza le regole seguenti per indicare un completamento invio all'applicazione (a seconda di come viene richiamato il metodo send, la notifica di completamento può essere la funzione restituisce da una chiamata di blocco, segnalazione di un evento o chiamando una funzione di notifica e così via):
  • Se il socket è ancora nell'ambito di contingenti SO_SNDBUF, Winsock copia i dati da inviare l'applicazione e indica il completamento dell'invio all'applicazione.
  • Se il socket è oltre la quota SO_SNDBUF ed è presente un solo invio precedentemente memorizzato nella cache del buffer di stack del kernel, Winsock copia i dati da inviare l'applicazione e indica il completamento dell'invio all'applicazione.
  • Se il socket è oltre la quota SO_SNDBUF ed è presente più di un buffer in precedenza inviare il buffer di stack del kernel, Winsock copia i dati da inviare l'applicazione. Winsock non indica il completamento dell'invio all'applicazione finché non lo stack viene completato sufficiente Invia per inserire il socket indietro all'interno della quota SO_SNDBUF o solo una condizione di attesa di invio.

Case Study 1

Panoramica:

Un client Winsock TCP deve inviare 10000 record a un server Winsock TCP per archiviare in un database. La dimensione dei record varia da 20 byte a 100 byte. Per semplificare la logica dell'applicazione, la progettazione è la seguente:
  • Il client esegue solo la trasmissione blocco. Il server non solo recv blocco.
  • Socket client imposta la SO_SNDBUF su 0 in modo che ogni record si spegne in un segmento di dati single.
  • Ricezione di chiamate del server in un ciclo. Il buffer registrato in ricezione è 200 byte, in modo che ogni record può essere ricevuto in una Ricevi chiamata.

Prestazioni:

Durante i test, lo sviluppatore rileva che il client può inviare solo cinque record al secondo al server. I 10000 record totali massimo 976K byte di dati (10000 * 100 / 1024), ha più di mezz'ora per l'invio al server.

Analisi:

Poiché il client non impostate l'opzione TCP_NODELAY, l'algoritmo Nagle impone lo stack TCP di attesa per un ACK prima può inviare un altro pacchetto sulla rete. Tuttavia, il client ha disattivato il buffering Winsock impostando l'opzione SO_SNDBUF a 0. Di conseguenza, i 10000 invia chiamate devono essere inviati e arrivata la notifica singolarmente. Ogni ACK è 200-ms ritardato perché si verifica quanto segue su stack TCP/IP del server:
  • Quando il server riceve un pacchetto, il timer del ritardo di 200 ms si spegne.
  • Il server non è necessario inviare qualsiasi elemento, in modo che non può essere piggyback l'ACK.
  • Il client non invia un altro pacchetto, a meno che non viene riconosciuto il pacchetto precedente.
  • Scadenza del timer di ritardo sul server e invia l'ACK.

Come migliorare:

Esistono due problemi con questo tipo di progetto. Innanzitutto, vi è il problema di timer di ritardo. Il client deve essere in grado di inviare due pacchetti al server entro i 200 ms poiché per impostazione predefinita, il client utilizza l'algoritmo Nagle, deve utilizzare solo il buffering di Winsock predefinito e non impostare SO_SNDBUF a 0. Una volta che lo stack TCP è fuse un buffer di dimensioni maggiore rispetto all'unità massima di trasmissione (MTU), viene inviato un pacchetto di dimensioni immediatamente senza attendere l'ACK dall'host remoto.

In secondo luogo, questo progetto richiede inviati ogni record di tali dimensioni ridotte. Questo invio di piccole dimensioni non è molto efficiente. In questo caso, lo sviluppatore possibile riempire ogni record di 100 byte e inviare 80 record alla volta da un client invia la chiamata. Per comunicare il server verrà inviato il numero di record in totale, il client possibile iniziare la comunicazione con un'intestazione di dimensioni correzione contenente il numero di record da seguire.

Case Study 2

Panoramica:

Un'applicazione client di Winsock TCP apre due connessioni con un'applicazione server di Winsock TCP che fornisce il servizio di quotazioni di borsa. La prima connessione viene utilizzata come un canale di comando per inviare il simbolo dell'azione al server. La seconda connessione viene utilizzata come un canale di dati per ricevere le quotazioni di borsa. Dopo che sono state stabilite le due connessioni, il client invia al server attraverso il canale di comando un simbolo azionario e attende la quotazione ritorno attraverso il canale di dati. La successiva richiesta del simbolo dell'azione Invia al server solo dopo che è stata ricevuta la prima quotazione. Il client e il server non impostare l'opzione SO_SNDBUF e TCP_NODELAY.

Prestazioni:

Durante i test, lo sviluppatore rileva che il client può ottenere solo le offerte di cinque al secondo.

Analisi:

Questa struttura consente solo una richiesta di quotazione sospeso alla volta. Il primo simbolo viene inviato al server tramite il canale dei comandi (connessione) e una risposta viene immediatamente inviata dal server al client tramite il canale dati (connessione). Quindi, il client invia immediatamente la seconda richiesta simbolo azionario e l'invia immediatamente restituisce come buffer nella chiamata Invia richiesta viene copiato nel buffer del kernel di Winsock. Tuttavia, lo stack TCP di client non può inviare la richiesta dal buffer del kernel immediatamente poiché il primo invio tramite il canale dei comandi non viene ancora riconosciuto. Dopo 200-ms ritardare timer a canale dei comandi server scade, ACK per la prima richiesta di simbolo viene restituita al client. Quindi, la seconda richiesta di offerta viene inviata correttamente al server dopo ritardi per l'offerta per il simbolo dell'azione secondo torna immediatamente attraverso il canale di dati poiché in questo momento, è scaduto il timer di ritardo a canale dati client 200-ms. Un ACK per la risposta offerta precedente viene ricevuto dal server. (Ricordate che il client potrebbe non inviare una richiesta di quotazione seconda di 200-ms, conferendovi il tempo per il timer di ritardo sul client per scadere e inviare un ACK al server). Di conseguenza, il client ottiene la seconda risposta offerta e può inviare un'altra richiesta di offerta, che presenta lo stesso ciclo.

Come migliorare:

Qui non è necessaria la progettazione di due connessioni (canale). Se si utilizza solo una connessione per la richiesta di quotazione dei titoli e la risposta, ACK per la richiesta di offerta può essere piggyback sulla risposta offerta e tornare immediatamente. Per migliorare ulteriormente le prestazioni, il client potrebbe "eseguire il multiplexing" più richieste di quotazioni di borsa in una chiamata di invio al server e il server potrebbe anche "eseguire il multiplexing" più risposte offerta in un'unica chiamata invia al client. Se la progettazione di due canali unidirezionali sia effettivamente necessaria per qualche motivo, entrambi i lati devono impostare l'opzione TCP_NODELAY in modo che i pacchetti di piccole dimensioni possono essere inviati immediatamente senza dover attendere un ACK per il pacchetto precedente.

Raccomandazioni:

Sebbene siano stati inseriti intenzionalmente questi due casi aziendali, contribuiscono a illustrare alcuni scenari peggiori. Quando si progetta un'applicazione che riguarda il segmento di numerosi dati di piccole dimensioni Invia e recvs, è necessario considerare le seguenti indicazioni:
  • Se i dati sono segmenti momento non critico, l'applicazione deve coalesce li in un blocco di dati più grande per passare a una chiamata di invio. Poiché il buffer di invio è destinato a essere copiati nel buffer del kernel di Winsock, il buffer non deve essere troppo grande. Un po' meno di 8K è solitamente efficace. Fino a quando il kernel Winsock Ottiene superiori alla MTU un blocco, invierà più pacchetti di dimensioni standard e un ultimo pacchetto con ciò che è a sinistra. Il lato di invio, tranne l'ultimo pacchetto non verrà raggiunto dal timer del ritardo di 200 ms. L'ultimo pacchetto, qualora dovesse essere un pacchetto dispari, è comunque soggetto all'algoritmo di riconoscimento ritardato. Se lo stack di fine invio Ottiene superiori alla MTU un altro blocco, può ignorare comunque l'algoritmo Nagle.
  • Se possibile, evitare le connessioni socket con il flusso di dati unidirezionale. Le comunicazioni tramite socket unidirezionali sono più facilmente subisca il Nagle e ritardato gli algoritmi di riconoscimento. Se la comunicazione dopo una richiesta e un flusso di risposta, è necessario utilizzare un singolo socket per effettuare invii e recvs in modo che il riconoscimento può essere piggyback sulla risposta.
  • Se tutti i segmenti di dati di piccole dimensioni devono essere inviati immediatamente, impostare l'opzione TCP_NODELAY dal lato del mittente.
  • A meno che non si desidera garantire il che invio di un pacchetto sulla rete quando un completamento invio è indicato da Winsock, è necessario non impostare il SO_SNDBUF a zero. Infatti, il buffer di 8k predefinito è stato determinato euristicamente per la maggior parte delle situazioni ed è consigliabile non modificare, a meno che non sono verificate che la nuova impostazione del buffer Winsock offre prestazioni migliori rispetto a quello predefinito. Inoltre, l'impostazione di SO_SNDBUF a zero per la maggior parte è vantaggioso per le applicazioni di trasferimento dei dati di massa. Anche in questo caso, per la massima efficienza è consigliabile utilizzare in combinazione con il doppio buffer (più di un invio sospeso in qualsiasi momento) e si operazioni dei / o sovrapposte.
  • Se la consegna dei dati non deve essere garantita, utilizzano il protocollo UDP.
Riferimenti
Per ulteriori informazioni sul riconoscimento ritardati e l'algoritmo Nagle, vedere il seguente:

Braden, R. [1989] RFC 1122, requisiti per Internet gli host, i livelli di comunicazione Internet Engineering Task Force.

Avviso: questo articolo è stato tradotto automaticamente

Proprietà

ID articolo: 214397 - Ultima revisione: 03/14/2015 07:00:00 - Revisione: 4.0

  • kbdswnet2003swept kbapi kbinfo kbip kbnetwork kbwinsock kbmt KB214397 KbMtit
Feedback
/c.microsoft.com/ms.js">