Código de controle SIO_SET_COMPATIBILITY_MODE
Descrição
O código de controle SIO_SET_COMPATIBILITY_MODE solicita como a pilha de rede deve lidar com determinados comportamentos para os quais a maneira padrão de lidar com o comportamento pode diferir entre as versões do Windows.
Para executar essa operação, chame a função WSAIoctl ou WSPIoctl com os parâmetros a seguir.
int WSAIoctl(
(socket) s, // descriptor identifying a socket
SIO_SET_COMPATIBILITY_MODE, // dwIoControlCode
(LPVOID) lpvInBuffer, // pointer to WSA_COMPATIBILITY_MODE struct
(DWORD) cbInBuffer, // length of input buffer
NULL, // output buffer
0, // size of output buffer
(LPDWORD) lpcbBytesReturned, // number of bytes returned
(LPWSAOVERLAPPED) lpOverlapped, // OVERLAPPED structure
(LPWSAOVERLAPPED_COMPLETION_ROUTINE) lpCompletionRoutine, // completion routine
);
int WSPIoctl(
(socket) s, // descriptor identifying a socket
SIO_SET_COMPATIBILITY_MODE, // dwIoControlCode
(LPVOID) lpvInBuffer, // pointer to WSA_COMPATIBILITY_MODE struct
(DWORD) cbInBuffer, // length of input buffer
NULL, // output buffer
0, // size of output buffer
(LPDWORD) lpcbBytesReturned, // number of bytes returned
(LPWSAOVERLAPPED) lpOverlapped, // OVERLAPPED structure
(LPWSAOVERLAPPED_COMPLETION_ROUTINE) lpCompletionRoutine, // completion routine
(LPWSATHREADID) lpThreadId, // a WSATHREADID structure
(LPINT) lpErrno // a pointer to the error code.
);
Parâmetros
s
Um descritor que identifica um soquete.
Dwiocontrolcode
O código de controle da operação. Use SIO_SET_COMPATIBILITY_MODE para esta operação.
Lpvinbuffer
Um ponteiro para o buffer de entrada. Esse parâmetro deve apontar para uma estrutura WSA_COMPATIBILITY_MODE .
Cbinbuffer
O tamanho, em bytes, do buffer de entrada. Esse parâmetro deve ser igual ou maior que o tamanho da estrutura WSA_COMPATIBILITY_MODE apontada pelo parâmetro lpvInBuffer .
Lpvoutbuffer
Um ponteiro para o buffer de saída. Esse parâmetro não é usado para essa operação.
cbOutBuffer
O tamanho, em bytes, do buffer de saída. Esse parâmetro deve ser definido como zero.
Lpcbbytesreturned
Um ponteiro para uma variável que recebe o tamanho, em bytes, dos dados armazenados no buffer de saída. Esse parâmetro retornado aponta para um valor DWORD igual a zero para essa operação, pois não há saída.
lpvOverlapped
Um ponteiro para uma estrutura WSAOVERLAPPED .
Se o soquete s tiver sido criado sem o atributo sobreposto, o parâmetro lpOverlapped será ignorado.
Se s tiver sido aberto com o atributo sobreposto e o parâmetro lpOverlapped não for NULL, a operação será executada como uma operação sobreposta (assíncrona). Nesse caso, o parâmetro lpOverlapped deve apontar para uma estrutura WSAOVERLAPPED válida.
Para operações sobrepostas, a função WSAIoctl ou WSPIoctl retorna imediatamente e o método de conclusão apropriado é sinalizado quando a operação é concluída. Caso contrário, a função não retornará até que a operação seja concluída ou ocorra um erro.
Lpcompletionroutine
Tipo: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
Um ponteiro para a rotina de conclusão chamado quando a operação foi concluída (ignorado para soquetes não sobrepostos).
lpThreadId
Um ponteiro para uma estrutura WSATHREADID a ser usada pelo provedor em uma chamada subsequente para WPUQueueApc. O provedor deve armazenar a estrutura WSATHREADID referenciada (não o ponteiro para o mesmo) até que a função WPUQueueApc retorne.
Nota Esse parâmetro se aplica somente à função WSPIoctl .
Lperrno
Um ponteiro para o código de erro.
Nota Esse parâmetro se aplica somente à função WSPIoctl .
Valor retornado
Se a operação for concluída com êxito, a função WSAIoctl ou WSPIoctl retornará zero.
Se a operação falhar ou estiver pendente, a função WSAIoctl ou WSPIoctl retornará SOCKET_ERROR. Para obter informações de erro estendidas, chame WSAGetLastError.
Código do erro | Significado |
---|---|
WSA_IO_PENDING | Uma operação sobreposta foi iniciada com êxito e a conclusão será indicada posteriormente. |
WSA_OPERATION_ABORTED | Uma operação sobreposta foi cancelada devido ao fechamento do soquete ou à execução do SIO_FLUSH comando IOCTL . |
WSAEFAULT | O parâmetro lpOverlapped ou lpCompletionRoutine não está totalmente contido em uma parte válida do espaço de endereço do usuário. |
WSAEINPROGRESS | A função é invocada quando um retorno de chamada está em andamento. |
WSAEINTR | Uma operação de bloqueio foi interrompida. |
WSAEINVAL | O parâmetro dwIoControlCode não é um comando válido ou um parâmetro de entrada especificado não é aceitável ou o comando não é aplicável ao tipo de soquete especificado. Esse erro será retornado se o parâmetro cbInBuffer for menor que o tamanho da estrutura WSA_COMPATIBILITY_MODE . |
WSAENETDOWN | O subsistema de rede falhou. |
WSAENOPROTOOPT | Não há suporte para a opção de soquete no protocolo especificado. |
WSAENOTCONN | O soquete s não está conectado. |
WSAENOTSOCK | O descritor s não é um soquete. |
WSAEOPNOTSUPP | Não há suporte para o comando IOCTL especificado. Esse erro será retornado se o SIO_SET_COMPATIBILITY_MODE IOCTL não tiver suporte do provedor de transporte. Esse erro também é retornado quando uma tentativa de usar o SIO_SET_COMPATIBILITY_MODE IOCTL é feita em um soquete de datagrama. |
Comentários
o SIO_SET_COMPATIBILITY_MODE IOCTL solicita como a pilha de rede deve lidar com determinados comportamentos para os quais a maneira padrão de lidar com o comportamento pode diferir entre as versões do Windows. A estrutura do argumento de entrada para SIO_SET_COMPATIBILITY_MODE é especificada na estrutura WSA_COMPATIBILITY_MODE definida no arquivo de cabeçalho Mswsockdef.h . Um ponteiro para a estrutura WSA_COMPATIBILITY_MODE é passado no parâmetro cbInBuffer . Essa estrutura é definida da seguinte maneira:
// Need to #include <mswsock.h>
/* Argument structure for SIO_SET_COMPATIBILITY_MODE */
typedef struct _WSA_COMPATIBILITY_MODE {
WSA_COMPATIBILITY_BEHAVIOR_ID BehaviorId;
ULONG TargetOsVersion;
} WSA_COMPATIBILITY_MODE, *PWSA_COMPATIBILITY_MODE;
O valor especificado no membro BehaviorId indica o comportamento solicitado. O valor especificado no membro TargetOsVersion indica a versão do Windows que está sendo solicitada para o comportamento.
O membro BehaviorId pode ser um dos valores do tipo de enumeração WSA_COMPATIBILITY_BEHAVIOR_ID definido no arquivo de cabeçalho Mswsockdef.h . Os valores possíveis para o membro BehaviorId são os seguintes:
Termo | Descrição |
---|---|
WsaBehaviorAll | Isso é equivalente a solicitar todos os possíveis comportamentos compatíveis definidos para WSA_COMPATIBILITY_BEHAVIOR_ID. |
WsaBehaviorReceiveBuffering | Quando o membro TargetOsVersion é definido como um valor para o Windows Vista ou posterior, as reduções no tamanho do buffer de recebimento TCP nesse soquete usando a opção de soquete SO_RCVBUF são permitidas mesmo após o estabelecimento de uma conexão TCP. Quando o membro TargetOsVersion é definido como um valor anterior ao Windows Vista, as reduções no tamanho do buffer de recebimento TCP nesse soquete usando a opção de soquete SO_RCVBUF não são permitidas após o estabelecimento da conexão. |
WsaBehaviorAutoTuning | Quando o membro TargetOsVersion é definido como um valor para o Windows Vista ou posterior, o ajuste automático da janela de recebimento é habilitado e o fator de escala da janela TCP é reduzido para 2 do valor padrão de 8. Quando TargetOsVersion é definido como um valor anterior ao Windows Vista, o ajuste automático da janela de recebimento é desabilitado. A opção de dimensionamento de janela TCP também está desabilitada e o tamanho máximo da janela de recebimento verdadeiro é limitado a 65.535 bytes. A opção de dimensionamento da janela TCP não poderá ser negociada na conexão mesmo que a opção de soquete SO_RCVBUF tenha sido chamada nesse soquete especificando um valor maior que 65.535 bytes antes da conexão ser estabelecida. |
O membro TargetOsVersion pode ser uma das constantes de versão NTDDI definidas no arquivo de cabeçalho Sdkddkver.h . Alguns dos valores possíveis para o membro TargetOsVersion são os seguintes:
Termo | Descrição |
---|---|
NTDDI_LONGHORN | O comportamento de destino é o padrão para o Windows Vista. |
NTDDI_WS03 | O comportamento de destino é o padrão para o Windows Server 2003. |
NTDDI_WINXP | O comportamento de destino é o padrão para o Windows XP. |
NTDDI_WIN2K | O comportamento de destino é o padrão para o Windows 2000. |
O principal impacto do membro TargetOsVersion é se esse membro é definido como um valor igual ou maior que NTDDI_LONGHORN.
O desempenho do TCP depende não apenas da taxa de transferência em si, mas sim do produto da taxa de transferência e do tempo de atraso de ida e volta. Esse produto de atraso de largura de banda mede a quantidade de dados que "preencheriam o pipe". Esse produto de atraso de largura de banda é o espaço de buffer necessário no remetente e no receptor para obter a taxa de transferência máxima na conexão TCP pelo caminho. Esse espaço em buffer representa a quantidade de dados não reconhecidos que o TCP deve manipular para manter o pipeline cheio. Problemas de desempenho de TCP surgem quando o produto com atraso de largura de banda é grande. Um caminho de rede que opera nessas condições geralmente é chamado de "pipe longo e gordo". Os exemplos incluem links satélite de pacote de alta capacidade, links sem fio de alta velocidade e links terrestres de fibra óptica em longas distâncias.
O cabeçalho TCP usa um campo de dados de 16 bits (o campo Janela no cabeçalho do pacote TCP) para relatar o tamanho da janela de recebimento ao remetente. Portanto, a maior janela que pode ser usada é de 65.535 bytes. Para contornar essa limitação, uma opção de extensão TCP, Escala de Janela TCP, foi adicionada para TCP de alto desempenho para permitir janelas maiores que 65.535 bytes. A opção Escala de Janela TCP (WSopt) é definida no RFC 1323 disponível no site do IETF. A extensão WSopt expande a definição da janela TCP para 32 bits usando um fator de escala logarítmica de um byte para estender o campo Janela de 16 bits no cabeçalho TCP. A extensão WSopt define um fator de escala implícito (2 para alguma potência), que é usado para multiplicar o valor de tamanho da janela encontrado em um cabeçalho TCP para obter o tamanho da janela real. Portanto, um fator de escala de janela de 8 resultaria em um tamanho de janela verdadeiro igual ao valor no campo Janela no cabeçalho TCP multiplicado por 2^8 ou 256. Portanto, se o campo Janela no cabeçalho TCP tiver sido definido como o valor máximo de 65.535 bytes e o fator de escala WSopt tiver sido negociado com um valor de 8, o tamanho da janela verdadeira será de 16.776.960 bytes.
O tamanho da janela de recebimento verdadeiro e, portanto, o fator de escala é determinado pelo espaço máximo do buffer de recebimento. Esse espaço máximo de buffer é a quantidade de dados que um receptor TCP permite que um remetente TCP envie antes de ter que aguardar uma confirmação. Depois que a conexão é estabelecida, o tamanho da janela de recebimento é anunciado em cada segmento TCP (o campo Janela no cabeçalho TCP). Anunciar a quantidade máxima de dados que o remetente pode enviar é um mecanismo de controle de fluxo do lado do receptor que impede o remetente de enviar dados que o receptor não pode armazenar. Um host de envio só pode enviar a quantidade máxima de dados anunciados pelo receptor antes de aguardar uma confirmação e uma atualização do tamanho da janela de recebimento.
No Windows Server 2003 e no Windows XP, o espaço máximo do buffer de recebimento que representa o tamanho da janela de recebimento para a pilha TCP/IP tem um valor padrão com base na velocidade do link da interface de envio. O valor real é ajustado automaticamente para incrementos pares do MSS (tamanho máximo do segmento) negociado durante o estabelecimento da conexão TCP. Portanto, para um link de 10 Mbit/s, o tamanho da janela de recebimento padrão normalmente seria definido como 16K bytes, enquanto em um link de 100 MBit/s o tamanho da janela de recebimento padrão seria definido como 65.535 bytes.
No Windows Server 2003 e no Windows XP, o tamanho da janela de recebimento máximo verdadeiro para a pilha TCP/IP pode ser configurado manualmente usando os seguintes valores de Registro em uma interface específica ou para todo o sistema:
HKEY_LOCAL_MACHINE\SYSTEM\Current Control Set\Services\Tcpip\Parameters\TCPWindowSize
HKEY_LOCAL_MACHINE\SYSTEM\Current Control Set\Services\Tcpip\Parameters\Interface\TCPWindowSize
O valor do Registro para TCPWindowSize pode ser definido como um máximo de 65.535 bytes quando não estiver usando a extensão WSopt ou um máximo de 1.073.741.823 bytes quando a extensão WSopt for usada (há suporte para um fator de escala máximo de 4). Sem o dimensionamento de janelas, um aplicativo só pode obter uma taxa de transferência de aproximadamente 5 megabits por segundo (Mbps) em um caminho com um RTT (tempo de ida e volta) de 100 milissegundos, independentemente da largura de banda do caminho. Essa taxa de transferência pode ser dimensionada para mais de um gigabit por segundo (Gbps) com dimensionamento de janela, o que permite que o TCP negocie o fator de dimensionamento para o tamanho da janela durante o estabelecimento da conexão.
No Windows Server 2003 e no Windows XP, a extensão WSopt pode ser habilitada definindo o valor do Registro a seguir.
HKEY_LOCAL_MACHINE\SYSTEM\Current Control Set\Services\Tcpip\Parameters\Tcp1323Opts
O valor do Registro Tcp1323Opts é um DWORD codificado de modo que, quando o bit 0 estiver definido, a extensão TCP WSopt esteja habilitada. Quando o bit 1 é definido, a opção TSopt (carimbo de data/hora TCP) definida no RFC 1323 é habilitada. Portanto, um valor de 1 ou 3 habilitará a extensão WSopt.
No Windows Server 2003 e no Windows XP, o padrão é que os valores de registro TCPWindowSize e Tcp1323Opts não sejam criados. Portanto, o padrão é que a extensão WSopt esteja desabilitada e o tamanho da janela de recebimento TCP seja definido pelo sistema para o valor máximo de até 65.535 bytes com base na velocidade do link. Quando o dimensionamento de janela está habilitado no Windows Server 2003 e no Windows XP definindo o valor do Registro Tcp1323Opts, o dimensionamento de janelas em uma conexão TCP ainda é usado apenas quando o remetente e o receptor incluem uma opção de escala de janela TCP no segmento SYN (sincronização) enviada umas às outras para negociar um fator de escala de janela. Quando o dimensionamento de janela é usado em uma conexão, o campo Janela no cabeçalho TCP é definido como 65.535 bytes e o fator de escala de janela é usado para ajustar o tamanho real da janela de recebimento para cima pelo fator de escala de janela negociado quando a conexão é estabelecida.
Um aplicativo pode especificar o tamanho da janela de recebimento TCP para uma conexão usando a opção de soquete SO_RCVBUF . O tamanho da janela de recebimento TCP para um soquete pode ser aumentado a qualquer momento usando SO_RCVBUF, mas ele só pode ser reduzido antes de estabelecer uma conexão. Para usar o dimensionamento de janela, um aplicativo deve especificar um tamanho de janela maior que 65.535 bytes ao usar a opção de soquete SO_RCVBUF antes que a conexão seja estabelecida.
O valor ideal para o tamanho da janela de recebimento TCP geralmente é difícil de determinar. Para preencher a capacidade da rede entre o remetente e o receptor, o tamanho da janela de recebimento deve ser definido como o produto de atraso de largura de banda para a conexão, que é a largura de banda multiplicada pelo tempo de ida e volta. Mesmo que um aplicativo possa determinar corretamente o produto de atraso de largura de banda, ainda não se sabe a rapidez com que o aplicativo receptor recuperará dados do buffer de dados de entrada (a taxa de recuperação do aplicativo). Apesar do suporte para dimensionamento de janela TCP, o tamanho máximo da janela de recebimento no Windows Server 2003 e no Windows XP ainda pode limitar a taxa de transferência porque é um tamanho máximo fixo para todas as conexões TCP (a menos que especificado por aplicativo usando SO_RCVBUF), o que pode aumentar a taxa de transferência para algumas conexões e diminuir a taxa de transferência para outras. Além disso, o tamanho máximo fixo da janela de recebimento para uma conexão TCP não varia com a alteração das condições de rede.
Para resolver o problema de determinar corretamente o valor do tamanho máximo da janela de recebimento para uma conexão TCP com base nas condições atuais da rede, a pilha TCP/IP no Windows Vista dá suporte a um recurso de ajuste automático da janela de recebimento. Quando esse recurso está habilitado, o ajuste automático da janela de recebimento determina continuamente o tamanho ideal da janela de recebimento verdadeiro medindo o produto de atraso de largura de banda e a taxa de recuperação do aplicativo e ajusta o tamanho máximo verdadeiro da janela de recebimento com base na alteração das condições de rede. O ajuste automático da janela de recebimento habilita a extensão TCP WSopt por padrão, permitindo até 16.776.960 bytes para o tamanho da janela verdadeira. À medida que os dados fluem pela conexão, a pilha TCP/IP monitora a conexão, mede o produto de atraso de largura de banda atual para a conexão e a taxa de recebimento do aplicativo e ajusta o tamanho real da janela de recebimento para otimizar a taxa de transferência. A pilha TCP/IP altera o valor do campo Janela no cabeçalho TCP com base nas condições de rede, uma vez que o fator de escala WSopt é corrigido quando a conexão é estabelecida pela primeira vez.
A pilha TCP/IP no Windows Vista não usa mais os valores do Registro TCPWindowSize . Com uma melhor taxa de transferência entre pares TCP, a utilização da largura de banda de rede aumenta durante a transferência de dados. Se todos os aplicativos forem otimizados para receber dados TCP, a utilização geral da rede poderá aumentar substancialmente, tornando o uso de QoS (Qualidade de Serviço) mais importante em redes que estão operando com ou perto da capacidade.
O comportamento padrão no Windows Vista para buffer de recebimento quando SIO_SET_COMPATIBILITY_MODE não é especificado usando WsaBehaviorReceiveBuffering é que nenhuma redução de tamanho de janela de recebimento usando SO_RCVBUF opção de soquete é permitida depois que uma conexão é estabelecida.
O comportamento padrão no Windows Vista para ajuste automático quando SIO_SET_COMPATIBILITY_MODE não é especificado usando WsaBehaviorAutoTuning é que a pilha receberá o ajuste automático da janela usando um fator de escala de janela de 8.
Observe que, se um aplicativo definir um tamanho de janela de recebimento válido com a opção de soquete SO_RCVBUF , a pilha usará o tamanho especificado e o ajuste automático de recebimento de janela será desabilitado.
O ajuste automático do Windows também pode ser desabilitado completamente usando o comando a seguir, , nesse caso, netsh interface tcp set global autotuninglevel=disabled
especificar WsaBehaviorAutoTuning não terá nenhum efeito.
O ajuste automático de recebimento de janela também pode ser desabilitado com base na política de grupo definida no Windows Server 2008.
A opção WsaBehaviorAutoTuning é necessária no Windows Vista para alguns dispositivos de gateway de Internet e firewalls que não dão suporte corretamente a fluxos de dados para conexões TCP que usam a extensão WSopt e um fator de escala do Windows. No Windows Vista, por padrão, um receptor negocia um fator de escala de janela de 8 para um tamanho máximo de janela verdadeira de 16.776.960 bytes. Quando os dados começam a fluir em um link rápido, o Windows começa inicialmente com um tamanho de janela verdadeiro de 64 Quilobytes definindo o campo Janela do cabeçalho TCP como 256 e definindo o fator de escala de janela como 8 nas opções TCP (256*2^8=64 KB). Alguns dispositivos e firewalls de gateway de Internet ignoram o fator de escala de janela e apenas olham para o campo janela anunciado no cabeçalho TCP especificado como 256 e removem pacotes de entrada para a conexão que contêm mais de 256 bytes de dados TCP. Para dar suporte ao dimensionamento da janela de recebimento TCP, um dispositivo de gateway ou firewall deve monitorar o handshake TCP e acompanhar o fator de escala de janela negociado como parte dos dados de conexão TCP. Além disso, alguns aplicativos e implementações de pilha TCP em outras plataformas ignoram a extensão TCP WSopt e o fator de dimensionamento de janela. Portanto, o host remoto que envia os dados pode enviar dados à taxa anunciada no campo Janela do cabeçalho TCP (256 bytes). Isso pode fazer com que os dados sejam recebidos muito lentamente pelo receptor.
Definir o membro BehaviorId como WsaBehaviorAutoTuning e TargetOsVersion para Windows Vista reduz o fator de escala de janela para 2, portanto, o campo Janela no cabeçalho TCP é inicialmente definido como 16.384 bytes e o fator de escala de janela é definido como 2 para um tamanho inicial de recebimento de janela verdadeira de 64K bytes.
O recurso de ajuste automático da janela pode aumentar o tamanho de recebimento da janela verdadeira para até 262.140 bytes definindo o campo Janela no cabeçalho TCP como 65.535 bytes.
Um aplicativo deve definir o SIO_SET_COMPATIBILITY_MODE IOCTL assim que um soquete for criado, pois essa opção não faz sentido nem se aplica depois que um SYN é enviado.
Definir essa opção tem o mesmo impacto que o seguinte comando: netsh interface tcp set global autotuninglevel=highlyrestricted
Observe que o arquivo de cabeçalho Mswsockdef.h é incluído automaticamente em Mswsock.h ou Netiodef.h e não deve ser usado diretamente.