Questões sobre estrutura - enviar segmentos de dados pequena através de TCP com o Winsock

Artigo: 214397 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

Quando necessitar de enviar pacotes de dados pequena através de TCP, a estrutura da sua aplicação Winsock é especialmente vital. Um design que não tem em consideração a interacção de confirmação adiada, Nagle algoritmo e Winsock memória intermédia drasticamente pode afectar o desempenho. Este artigo aborda estas questões, utilizando um par de casos práticos e deriva de uma série de recomendações para enviar pacotes de dados pequena eficiente de uma aplicação Winsock.

Mais Informação

Fundo

Quando uma pilha Microsoft TCP recebe um pacote de dados, um temporizador de atraso de 200 ms vai. Quando um ACK, eventualmente, é enviado, o temporizador de atraso é reposto e iniciará outro 200 ms atraso quando é recebido o seguinte pacote de dados. Para aumentar a eficiência em Internet e as aplicações de intranet, a pilha Microsoft TCP utiliza os seguintes critérios para decidir quando enviar um ACK em pacotes de dados recebidos:
  • Se for recebido o segundo pacote de dados antes de expira o temporizador de atraso, a ACK é enviada.
  • Se existirem dados enviados na mesma direcção como o ACK antes do segundo pacote de dados é recebido e o atraso de temporizador expira, o ACK é piggybacked com o segmento de dados e enviada imediatamente.
  • Quando o temporizador de atraso expira, o ACK é enviada.
Para evitar a pacotes de dados pequena congest da rede, a pilha Microsoft TCP permite o algoritmo Nagle por predefinição, coalesces uma memória intermédia pequenas de dados de várias chamadas de envio e atrasos enviar que até um ACK para o pacote de dados anterior enviado recebido do anfitrião remoto. Seguem-se duas excepções para o algoritmo Nagle:
  • Se a pilha tem coalesced uma memória intermédia dados maior do que a máxima de transmissão unidade MTU, Maximum Transmission (Unit), um pacote de tamanho completo é enviado imediatamente sem aguardar ACK do anfitrião remoto. Numa rede Ethernet, a MTU para TCP/IP é 1460 bytes.
  • A opção de socket TCP_NODELAY é aplicada a desactivar o algoritmo Nagle para que os pacotes de dados pequenos são transmitidos ao anfitrião remoto sem atraso.
Para optimizar o desempenho na camada de aplicação, memórias intermédias de dados do Winsock cópias de aplicação enviam chamadas para uma memória intermédia kernel de Winsock. Em seguida, a pilha utiliza a suas próprias heurística (tal como algoritmo Nagle) para determinar quando, na realidade, colocar o pacote de cabos. Pode alterar a quantidade de memória intermédia de kernel Winsock atribuída ao socket utilizando a opção de SO_SNDBUF (é 8 K por predefinição). Se necessário, Winsock pode buffer significativamente mais do que o SO_SNDBUF tamanho da memória intermédia. Na maioria dos casos, o concluído o envio da aplicação indica apenas a memória intermédia de dados numa aplicação enviar chamada é copiada para a memória intermédia kernel de Winsock e não indica que os dados atingiu o suporte de rede. A única excepção é quando desactiva a memória intermédia Winsock definindo SO_SNDBUF como 0.

Winsock utiliza as seguintes regras para indicar uma conclusão de envio para a aplicação (dependendo de como é invocado o envio, a notificação de conclusão pode ser a função devolver de uma chamada de bloqueio, um evento de sinalização ou chamar uma função de notificação e por aí em diante):
  • Se o socket ainda de quota SO_SNDBUF, Winsock copia os dados de envio de aplicação e indica a conclusão de envio para a aplicação.
  • Se o socket é SO_SNDBUF quota e existe apenas um envio anteriormente na memória intermédia ainda na memória intermédia de kernel de pilha, Winsock copia os dados de envio de aplicação e indica a conclusão de envio para a aplicação.
  • Se o socket é SO_SNDBUF quota e existir mais do que uma previamente armazenada em buffer enviar na memória intermédia pilha kernel, Winsock copia os dados de envio da aplicação. Winsock não indica a conclusão de envio para a aplicação até que a pilha completa suficiente envia para colocar o socket novamente dentro de quota SO_SNDBUF ou apenas uma condição de envio pendentes.

Caso prático 1

Descrição geral:

Um cliente de TCP WinSock necessita de enviar 10000 registos para um servidor TCP WinSock para armazenar na base de dados. Varia o tamanho dos registos de 20 bytes para 100 bytes. Para simplificar a lógica da aplicação, a estrutura é como se segue:
  • O cliente não enviar bloqueio apenas. O servidor não só recv bloqueio.
  • O socket cliente define a SO_SNDBUF para 0 para que cada registo vai um segmento de dados único.
  • O servidor chama recv num ciclo. A memória intermédia registada recv é 200 bytes para que cada registo pode ser recebido no uma recv chamada.

Desempenho:

Durante os testes, o programador localiza que o cliente só pode enviar cinco registos por segundo para o servidor. O total de 10000 registos, máximo no 976 K bytes de dados (10000 * 100 / 1024), tem mais de metade uma hora para enviar para o servidor.

Análise:

Uma vez que o cliente não define a opção TCP_NODELAY, o algoritmo Nagle força a pilha TCP para aguardar um ACK possa enviar outro pacote durante a ligação. No entanto, o cliente desactivou a memória intermédia Winsock, definindo a opção de SO_SNDBUF para 0. Por conseguinte, o 10000 enviar chama ter para ser enviada e ACK'ed individualmente. Cada ACK é adiadas 200-ms porque ocorre o seguinte na pilha TCP do servidor:
  • Quando o servidor recebe um pacote, o temporizador de atraso 200 ms vai.
  • O servidor não é necessário enviar novamente, nada para que o ACK não pode ser piggybacked.
  • O cliente não enviará outro pacote a menos que o pacote anterior é reconhecido.
  • O temporizador de atraso no servidor expira e é devolvida a ACK.

Como aumentar o:

Existem dois problemas com esta estrutura. Em primeiro lugar, existe o problema de temporizador de atraso. O cliente tem de ser capaz de enviar dois pacotes para o servidor de 200 ms. uma vez que o cliente utiliza o algoritmo Nagle por predefinição, deverá utilizar predefinição Winsock memória intermédia e não defina SO_SNDBUF como 0. Quando a pilha TCP tem coalesced uma memória intermédia maior do que a máxima de transmissão unidade MTU, Maximum Transmission (Unit), um pacote de tamanho completo é enviado imediatamente sem aguardar ACK do anfitrião remoto.

Em segundo lugar, esta estrutura chama um envio para cada registo esse tamanho pequeno. Enviar este pequeno de um tamanho não é muito eficiente. Neste caso, o programador querer cada registo para 100 bytes de preenchimento e enviar 80 registos ao mesmo tempo um cliente enviar chamada. Para permitir que o servidor sabe quantos registos serão enviados em total, o cliente poderá pretender começar a desactivar a comunicação com um cabeçalho de tamanho de correcção que contém o número de registos a seguir.

Caso prático 2

Descrição geral:

Uma aplicação de cliente TCP WinSock abre duas ligações com uma aplicação de servidor TCP WinSock fornecer serviços de cotações da bolsa. A primeira ligação é utilizada como um canal de comando para enviar o símbolo da acção para o servidor. A segunda ligação é utilizada como um canal de dados para receber a cotação de acções. Depois de tem sido estabelecidas duas ligações, o cliente envia um símbolo de cotações para o servidor através do canal de comando e aguarda a cotação de acções devolvidas através do canal de dados. Envia o pedido de símbolo de cotações seguinte para o servidor apenas depois de cotações primeira foi recebida. O cliente e o servidor não definem a opção SO_SNDBUF e TCP_NODELAY.

Desempenho:

Durante os testes, o programador localiza que o cliente só é possível obter cinco propostas por segundo.

Análise:

Esta estrutura permite apenas um pedido de cotação de acções pendentes ao mesmo tempo. Símbolo da acção primeiro é enviado ao servidor através do canal de comando (ligação) e é enviada uma resposta imediatamente a partir do servidor para o cliente através do canal de dados (ligação). Em seguida, o cliente envia imediatamente o segundo pedido de símbolo de cotações e a enviar devolve imediatamente à medida que a memória intermédia pedido na chamada de envio é copiada para a memória intermédia kernel de Winsock. No entanto, a pilha TCP do cliente não consegue enviar o pedido a partir da respectiva memória intermédia kernel imediatamente uma vez que o primeiro enviar através do canal de comando não for confirmado ainda. Depois dos ms 200 atrasar temporizador no canal de comandos do servidor expira, ACK para o primeiro pedido de símbolo devolvida ao cliente. Em seguida, o segundo pedido de proposta com êxito é enviado para o servidor após seja atrasada para 200-ms. que a proposta para o símbolo de cotações segundo devolvida imediatamente através do canal de dados porque, neste momento, o temporizador de atraso no canal de dados cliente expirou. Um ACK para a resposta proposta anterior é recebido pelo servidor. (Lembre-se de que o cliente não conseguiu enviar um pedido de cotações segundo de 200-ms, assim dar tempo para o temporizador de atraso no cliente para expirar e enviar um ACK para o servidor.) Como resultado, o cliente obtém a segunda resposta de proposta e pode emitir outro pedido de proposta, que é sujeito ao ciclo de mesmo.

Como aumentar o:

A estrutura de ligação de dois (canal) é necessário aqui. Se utilizar apenas uma ligação para o pedido de cotação de acções e a resposta, pode ser piggybacked na resposta proposta e voltar imediatamente ACK para o pedido de proposta. Para melhorar ainda mais o desempenho, o cliente foi "multiplex" vários pedidos de cotações para uma chamada de envio para o servidor e o servidor pode também "multiplex" várias respostas de proposta para uma chamada de envio para o cliente. Se a estrutura de dois canais unidireccional é realmente necessária por alguma razão, ambos os lados deverão definir a opção TCP_NODELAY para que os pacotes pequenos podem ser enviados imediatamente sem ter de aguardar um ACK para o pacote anterior.

Recomendações:

Apesar destes dois casos práticos são fabricated, elas ajudam a para ilustrar alguns cenários piores caso. Ao estruturar uma aplicação que envolve o segmento de dados pequena extensa envia e recvs, deverá considerar as seguintes directrizes:
  • Se os dados são segmentos de tempo não críticas, a aplicação deve adesão-los para um maior bloco de dados para passar para uma chamada de envio. Uma vez que a memória intermédia de envio é provável que sejam copiados para a memória intermédia kernel de Winsock, a memória intermédia não deve ser demasiado grande. Um pouco menos de 8 K é normalmente eficaz. Desde que o kernel Winsock obtém um bloco superior a MTU, enviará vários pacotes de tamanho completo e o último pacote com que fica. O lado de envio, excepto o último pacote, não irá ser atingido pelo temporizador de atraso ms 200. O último pacote, se este ser um pacote ímpar, está ainda sujeita ao algoritmo de atraso de confirmação. Se a pilha de fim envio obtiver outro bloco superior a MTU, ainda pode ignorar a algoritmo Nagle.
  • Se possível, evite ligações de socket com fluxo de dados unidireccional. Comunicações através de sockets unidireccionais são mais afectados pelo Nagle e facilmente atrasada algoritmos de confirmação. Se a comunicação segue um pedido e um fluxo de resposta, deverá utilizar um socket único fazer envia e recvs para que o ACK pode ser piggybacked na resposta.
  • Se todos os segmentos de dados pequena têm de ser imediatamente enviada, defina opção TCP_NODELAY na extremidade de envio.
  • A menos que pretenda garante que um pacote é enviado durante a ligação quando uma conclusão de envio é indicada pelo Winsock, não deve definir o SO_SNDBUF para zero. Na realidade, a memória intermédia 8 K de predefinição foi determinada heuristically a funcionar bem para a maior parte das situações e deve não altere-a menos que tenha testado que a nova definição de memória intermédia do Winsock permite um melhor desempenho do que a predefinição. Além disso, definir SO_SNDBUF para zero é principalmente útil para aplicações que em massa transferência de dados. Mesmo assim, para eficiência máxima deve utilizar em conjunto com duplo (mais do que um envio pendente num dado momento) de memória intermédia e E/s sobrepostas.
  • Se a entrega de dados não tem de ser garantida, utilize UDP.

Referências

Para obter mais informações sobre adiada confirmação e o algoritmo Nagle, consulte o seguinte:

Braden, r. [1989], RFC 1122, Requirements for Internet Hosts--camadas de comunicação, Internet Engineering Task Force.

Propriedades

Artigo: 214397 - Última revisão: segunda-feira, 11 de Julho de 2005 - Revisão: 3.1
A informação contida neste artigo aplica-se a:
  • Microsoft Platform Software Development Kit-January 2000 Edition
Palavras-chave: 
kbmt kbdswnet2003swept kbapi kbinfo kbip kbnetwork kbwinsock KB214397 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 214397

Submeter comentários