código de control de SIO_SET_COMPATIBILITY_MODE

Descripción

El SIO_SET_COMPATIBILITY_MODE código de control solicita cómo la pila de redes debe controlar determinados comportamientos para los que la forma predeterminada de controlar el comportamiento puede diferir en todas las versiones de Windows.

Para realizar esta operación, llame a la función WSAIoctl o WSPIoctl con los parámetros siguientes.

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

Descriptor que identifica un socket.

dwIoControlCode

Código de control para la operación. Use SIO_SET_COMPATIBILITY_MODE para esta operación.

lpvInBuffer

Puntero al búfer de entrada. Este parámetro debe apuntar a una estructura de WSA_COMPATIBILITY_MODE .

cbInBuffer

Tamaño, en bytes, del búfer de entrada. Este parámetro debe ser igual o mayor que el tamaño de la estructura de WSA_COMPATIBILITY_MODE a la que apunta el parámetro lpvInBuffer .

lpvOutBuffer

Puntero al búfer de salida. Este parámetro no se usa para esta operación.

cbOutBuffer

Tamaño, en bytes, del búfer de salida. Este parámetro debe establecerse en cero.

lpcbBytesReturned

Puntero a una variable que recibe el tamaño, en bytes, de los datos almacenados en el búfer de salida. Este parámetro devuelto apunta a un valor DWORD de cero para esta operación, ya que no hay salida.

lpvOverlapped

Puntero a una estructura WSAOVERLAPPED .

Si el socket se creó sin el atributo superpuesto, se omite el parámetro lpOverlapped .

Si se abrió con el atributo superpuesto y el parámetro lpOverlapped no es NULL, la operación se realiza como una operación superpuesta (asincrónica). En este caso, el parámetro lpOverlapped debe apuntar a una estructura WSAOVERLAPPED válida.

En el caso de las operaciones superpuestas, la función WSAIoctl o WSPIoctl devuelve inmediatamente y el método de finalización adecuado se señala cuando se ha completado la operación. De lo contrario, la función no devuelve hasta que se haya completado la operación o se produzca un error.

lpCompletionRoutine

Tipo: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

Puntero a la rutina de finalización a la que se llama cuando se ha completado la operación (se omite para sockets no superpuestos).

lpThreadId

Puntero a una estructura WSATHREADID que va a usar el proveedor en una llamada posterior a WPUQueueApc. El proveedor debe almacenar la estructura WSATHREADID a la que se hace referencia (no el puntero a la misma) hasta que se devuelva la función WPUQueueApc .

Nota Este parámetro solo se aplica a la función WSPIoctl .

lpErrno

Puntero al código de error.

Nota Este parámetro solo se aplica a la función WSPIoctl .

Valor devuelto

Si la operación se completa correctamente, la función WSAIoctl o WSPIoctl devuelve cero.

Si se produce un error en la operación o está pendiente, la función WSAIoctl o WSPIoctl devuelve SOCKET_ERROR. Para obtener información de error extendida, llame a WSAGetLastError.

Código de error Significado
WSA_IO_PENDING Una operación superpuesta se inició correctamente y la finalización se indicará en un momento posterior.
WSA_OPERATION_ABORTED Se canceló una operación superpuesta debido al cierre del socket o a la ejecución del comando SIO_FLUSH IOCTL.
WSAEFAULT El parámetro lpOverlapped o lpCompletionRoutine no está totalmente incluido en una parte válida del espacio de direcciones del usuario.
WSAEINPROGRESS La función se invoca cuando hay una devolución de llamada en curso.
WSAEINTR Se interrumpió una operación de bloqueo.
WSAEINVAL El parámetro dwIoControlCode no es un comando válido o un parámetro de entrada especificado no es aceptable o el comando no es aplicable al tipo de socket especificado. Este error se devuelve si el parámetro cbInBuffer es menor que el tamaño de la estructura WSA_COMPATIBILITY_MODE .
WSAENETDOWN Error en el subsistema de red.
WSAENOPROTOOPT La opción de socket no se admite en el protocolo especificado.
WSAENOTCONN El socket s no está conectado.
WSAENOTSOCK El descriptor s no es un socket.
WSAEOPNOTSUPP No se admite el comando IOCTL especificado. Este error se devuelve si el proveedor de transporte no admite el SIO_SET_COMPATIBILITY_MODE IOCTL. Este error también se devuelve cuando se intenta usar el SIO_SET_COMPATIBILITY_MODE IOCTL en un socket de datagramas.

Comentarios

el SIO_SET_COMPATIBILITY_MODE IOCTL solicita cómo debe controlar la pila de redes determinados comportamientos para los que la forma predeterminada de controlar el comportamiento puede diferir en todas las versiones de Windows. La estructura del argumento de entrada para SIO_SET_COMPATIBILITY_MODE se especifica en la estructura de WSA_COMPATIBILITY_MODE definida en el archivo de encabezado Mswsockdef.h . Se pasa un puntero a la estructura WSA_COMPATIBILITY_MODE en el parámetro cbInBuffer . Esta estructura se define de la siguiente manera:

// 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;

El valor especificado en el miembro BehaviorId indica el comportamiento solicitado. El valor especificado en el miembro TargetOsVersion indica la versión de Windows que se solicita para el comportamiento.

El miembro BehaviorId puede ser uno de los valores del tipo de enumeración WSA_COMPATIBILITY_BEHAVIOR_ID definido en el archivo de encabezado Mswsockdef.h . Los valores posibles para el miembro BehaviorId son los siguientes:

Término Descripción
WsaBehaviorAll Esto equivale a solicitar todos los posibles comportamientos compatibles definidos para WSA_COMPATIBILITY_BEHAVIOR_ID.
WsaBehaviorReceiveBuffering Cuando el miembro TargetOsVersion se establece en un valor para Windows Vista o posterior, se permiten reducciones en el tamaño del búfer de recepción TCP en este socket mediante la opción de socket SO_RCVBUF incluso después de que se haya establecido una conexión TCP. Cuando el miembro TargetOsVersion se establece en un valor anterior a Windows Vista, no se permiten reducciones en el tamaño del búfer de recepción TCP en este socket mediante la opción de socket SO_RCVBUF después del establecimiento de la conexión.
WsaBehaviorAutoTuning Cuando el miembro TargetOsVersion se establece en un valor para Windows Vista o posterior, se habilita el ajuste automático de la ventana de recepción y el factor de escala de ventanas TCP se reduce a 2 del valor predeterminado de 8. Cuando TargetOsVersion se establece en un valor anterior a Windows Vista, se deshabilita el ajuste automático de la ventana de recepción. La opción de escalado de ventanas TCP también está deshabilitada y el tamaño máximo real de la ventana de recepción está limitado a 65 535 bytes. La opción de escalado de ventanas TCP no se puede negociar en la conexión incluso si se llamó a la opción de socket SO_RCVBUF en este socket especificando un valor superior a 65 535 bytes antes de establecer la conexión.

El miembro TargetOsVersion puede ser una de las constantes de versión NTDDI definidas en el archivo de encabezado Sdkddkver.h . Algunos de los valores posibles para el miembro TargetOsVersion son los siguientes:

Término Descripción
NTDDI_LONGHORN El comportamiento de destino es el predeterminado para Windows Vista.
NTDDI_WS03 El comportamiento de destino es el predeterminado para Windows Server 2003.
NTDDI_WINXP El comportamiento de destino es el predeterminado para Windows XP.
NTDDI_WIN2K El comportamiento de destino es el predeterminado para Windows 2000.

El impacto principal del miembro TargetOsVersion es si este miembro está establecido en un valor igual o mayor que NTDDI_LONGHORN.

El rendimiento de TCP no solo depende de la velocidad de transferencia, sino del producto de la velocidad de transferencia y del tiempo de retraso de ida y vuelta. Este producto de retraso de ancho de banda mide la cantidad de datos que "llenarían la tubería". Este producto de retraso de ancho de banda es el espacio de búfer necesario en el remitente y el receptor para obtener el rendimiento máximo en la conexión TCP a través de la ruta de acceso. Este espacio de búfer representa la cantidad de datos no reconocidos que TCP debe controlar para mantener la canalización llena. Los problemas de rendimiento de TCP surgen cuando el producto de retraso de ancho de banda es grande. Una ruta de acceso de red que funciona en estas condiciones se suele denominar "tubo largo y gordo". Algunos ejemplos son los enlaces satélite de paquetes de alta capacidad, los enlaces inalámbricos de alta velocidad y los enlaces ópticos de fibra terrestre a largo plazo.

El encabezado TCP usa un campo de datos de 16 bits (el campo Ventana en el encabezado de paquete TCP) para notificar el tamaño de la ventana de recepción al remitente. Por lo tanto, la ventana más grande que se puede usar es de 65 535 bytes. Para eludir esta limitación, se agregó una opción de extensión TCP, escala de ventanas TCP, para tcp de alto rendimiento para permitir ventanas de más de 65 535 bytes. La opción Escala de ventanas TCP (WSopt) se define en RFC 1323 disponible en el sitio web de IETF. La extensión WSopt expande la definición de la ventana TCP a 32 bits mediante un factor de escala logarítmica de un byte para extender el campo Ventana de 16 bits en el encabezado TCP. La extensión WSopt define un factor de escala implícito (de 2 a alguna potencia), que se usa para multiplicar el valor de tamaño de ventana que se encuentra en un encabezado TCP para obtener el tamaño de ventana verdadero. Por lo tanto, un factor de escala de ventanas de 8 daría como resultado un tamaño de ventana verdadero igual al valor del campo Ventana del encabezado TCP multiplicado por 2^8 o 256. Por lo tanto, si el campo Ventana del encabezado TCP se estableció en el valor máximo de 65 535 bytes y el factor de escala de WSopt se negoció en un valor de 8, el tamaño de ventana verdadero sería de 16 776 960 bytes.

El tamaño verdadero de la ventana de recepción y, por tanto, el factor de escala viene determinado por el espacio máximo del búfer de recepción. Este espacio máximo de búfer es la cantidad de datos que un receptor TCP permite que un remitente TCP envíe antes de tener que esperar una confirmación. Una vez establecida la conexión, el tamaño de la ventana de recepción se anuncia en cada segmento TCP (el campo Ventana del encabezado TCP). La publicidad de la cantidad máxima de datos que el remitente puede enviar es un mecanismo de control de flujo del lado receptor que impide que el remitente envíe datos que el receptor no puede almacenar. Un host de envío solo puede enviar la cantidad máxima de datos anunciados por el receptor antes de esperar una confirmación y una actualización de tamaño de ventana de recepción.

En Windows Server 2003 y Windows XP, el espacio de búfer de recepción máximo que representa el tamaño de la ventana de recepción para la pila TCP/IP tiene un valor predeterminado basado en la velocidad de vínculo de la interfaz de envío. El valor real se ajusta automáticamente a incrementos pares del tamaño máximo de segmento (MSS) negociado durante el establecimiento de la conexión TCP. Por lo tanto, para un vínculo de 10 Mbit/s, el tamaño predeterminado de la ventana de recepción normalmente se establecería en 16 000 bytes, mientras que en un vínculo de 100 MBit/s, el tamaño predeterminado de la ventana de recepción se establecería en 65 535 bytes.

En Windows Server 2003 y Windows XP, el tamaño máximo real de la ventana de recepción para la pila TCP/IP se puede configurar manualmente con los siguientes valores del Registro en una interfaz específica o para todo el sistema:

HKEY_LOCAL_MACHINE\SYSTEM\Current Control Set\Services\Tcpip\Parameters\TCPWindowSize

HKEY_LOCAL_MACHINE\SYSTEM\Current Control Set\Services\Tcpip\Parameters\Interface\TCPWindowSize

El valor del Registro para TCPWindowSize se puede establecer en un máximo de 65 535 bytes cuando no se usa la extensión WSopt o un máximo de 1073 741 823 bytes cuando se usa la extensión WSopt (se admite un factor de escala máximo de 4). Sin escalado de ventanas, una aplicación solo puede lograr un rendimiento de aproximadamente 5 megabits por segundo (Mbps) en una ruta de acceso con un tiempo de ida y vuelta (RTT) de 100 milisegundos, independientemente del ancho de banda de la ruta de acceso. Este rendimiento se puede escalar a más de un gigabit por segundo (Gbps) con escalado de ventanas, lo que permite que TCP negocie el factor de escala para el tamaño de la ventana durante el establecimiento de la conexión.

En Windows Server 2003 y Windows XP, la extensión WSopt se puede habilitar estableciendo el siguiente valor del Registro.

HKEY_LOCAL_MACHINE\SYSTEM\Current Control Set\Services\Tcpip\Parameters\Tcp1323Opts

El valor del Registro Tcp1323Opts es un DWORD codificado de forma que, cuando se establece el bit 0, la extensión TCP WSopt está habilitada. Cuando se establece el bit 1, la opción marca de tiempo TCP (TSopt) definida en RFC 1323 está habilitada. Por lo tanto, un valor de 1 o 3 habilitará la extensión WSopt.

En Windows Server 2003 y Windows XP, el valor predeterminado es que no se crean los valores del Registro TCPWindowSize y Tcp1323Opts. Por lo tanto, el valor predeterminado es que la extensión WSopt está deshabilitada y el tamaño de la ventana de recepción TCP se establece por el sistema en un valor máximo de hasta 65 535 bytes en función de la velocidad del vínculo. Cuando el escalado de ventanas está habilitado en Windows Server 2003 y Windows XP estableciendo el valor del Registro Tcp1323Opts, el escalado de ventanas en una conexión TCP solo se usa cuando tanto el remitente como el receptor incluyen una opción de escala de ventana TCP en el segmento sincronizar (SYN) enviado entre sí para negociar un factor de escala de ventanas. Cuando se usa el escalado de ventanas en una conexión, el campo Ventana del encabezado TCP se establece en 65 535 bytes y el factor de escala de ventanas se usa para ajustar el tamaño real de la ventana de recepción hacia arriba por el factor de escala de ventana negociado cuando se establece la conexión.

Una aplicación puede especificar el tamaño de la ventana de recepción TCP para una conexión mediante la opción de socket SO_RCVBUF . El tamaño de la ventana de recepción TCP para un socket se puede aumentar en cualquier momento mediante SO_RCVBUF, pero solo se puede reducir antes de establecer una conexión. Para usar el escalado de ventanas, una aplicación debe especificar un tamaño de ventana superior a 65 535 bytes al usar la opción de socket SO_RCVBUF antes de establecer la conexión.

El valor ideal para el tamaño de la ventana de recepción TCP suele ser difícil de determinar. Para rellenar la capacidad de la red entre el remitente y el receptor, el tamaño de la ventana de recepción debe establecerse en el producto de retraso de ancho de banda para la conexión, que es el ancho de banda multiplicado por el tiempo de ida y vuelta. Incluso si una aplicación puede determinar correctamente el producto de retraso de ancho de banda, todavía no se sabe la rapidez con la que la aplicación receptora recuperará los datos del búfer de datos entrantes (la tasa de recuperación de la aplicación). A pesar de la compatibilidad con el escalado de ventana TCP, el tamaño máximo de la ventana de recepción en Windows Server 2003 y Windows XP todavía puede limitar el rendimiento porque es un tamaño máximo fijo para todas las conexiones TCP (a menos que se especifique por aplicación mediante SO_RCVBUF), lo que puede mejorar el rendimiento de algunas conexiones y reducir el rendimiento para otros. Además, el tamaño de ventana de recepción máximo fijo para una conexión TCP no varía con las condiciones de red cambiantes.

Para resolver el problema de determinar correctamente el valor del tamaño máximo de la ventana de recepción para una conexión TCP en función de las condiciones actuales de la red, la pila TCP/IP de Windows Vista admite una característica de ajuste automático de ventanas de recepción. Cuando esta característica está habilitada, el ajuste automático de la ventana de recepción determina continuamente el tamaño óptimo de la ventana de recepción real mediante la medición del producto de retraso de ancho de banda y la tasa de recuperación de la aplicación, y ajusta el tamaño máximo real de la ventana de recepción en función de las condiciones de red cambiantes. El ajuste automático de la ventana de recepción habilita la extensión TCP WSopt de forma predeterminada, lo que permite hasta 16 776 960 bytes para el tamaño de ventana verdadero. A medida que los datos fluyen a través de la conexión, la pila TCP/IP supervisa la conexión, mide el producto actual de retraso de ancho de banda para la conexión y la velocidad de recepción de la aplicación, y ajusta el tamaño real de la ventana de recepción para optimizar el rendimiento. La pila TCP/IP cambia el valor del campo Ventana en el encabezado TCP en función de las condiciones de red, ya que el factor de escala de WSopt se fija cuando se establece la conexión por primera vez.

La pila TCP/IP de Windows Vista ya no usa los valores del Registro TCPWindowSize . Con un mejor rendimiento entre los pares TCP, el uso del ancho de banda de red aumenta durante la transferencia de datos. Si todas las aplicaciones están optimizadas para recibir datos TCP, el uso general de la red puede aumentar considerablemente, lo que hace que el uso de calidad de servicio (QoS) sea más importante en las redes que funcionan a una capacidad cercana o en funcionamiento.

El comportamiento predeterminado en Windows Vista para recibir búfer cuando no se especifica SIO_SET_COMPATIBILITY_MODE mediante WsaBehaviorReceiveBuffering es que no se permiten reducciones de tamaño de ventana de recepción mediante SO_RCVBUF opción de socket después de establecer una conexión.

El comportamiento predeterminado en Windows Vista para el ajuste automático cuando no se especifica SIO_SET_COMPATIBILITY_MODE mediante WsaBehaviorAutoTuning es que la pila recibirá el ajuste automático de ventanas mediante un factor de escala de ventanas de 8. Tenga en cuenta que si una aplicación establece un tamaño de ventana de recepción válido con la opción de socket SO_RCVBUF , la pila usará el tamaño especificado y la ventana recibirá el ajuste automático se deshabilitará. El ajuste automático de Windows también puede deshabilitarse completamente con el siguiente comando, netsh interface tcp set global autotuninglevel=disabled, en cuyo caso especificar WsaBehaviorAutoTuning no tendrá ningún efecto. El ajuste automático de recepción de ventanas también se puede deshabilitar en función de la directiva de grupo establecida en Windows Server 2008.

La opción WsaBehaviorAutoTuning es necesaria en Windows Vista para algunos dispositivos y firewalls de puerta de enlace de Internet que no admiten correctamente flujos de datos para conexiones TCP que usan la extensión WSopt y un factor de escala de Windows. En Windows Vista, un receptor negocia de forma predeterminada un factor de escala de ventanas de 8 para un tamaño máximo de ventana real de 16 776 960 bytes. Cuando los datos comienzan a fluir en un vínculo rápido, Windows comienza inicialmente con un tamaño de ventana true de 64 kilobytes estableciendo el campo Ventana del encabezado TCP en 256 y estableciendo el factor de escala de ventana en 8 en las opciones TCP (256*2^8=64KB). Algunos dispositivos y firewalls de puerta de enlace de Internet omiten el factor de escala de ventanas y solo examinan el campo Ventana anunciado en el encabezado TCP especificado como 256 y quitan los paquetes entrantes de la conexión que contienen más de 256 bytes de datos TCP. Para admitir el escalado de ventanas de recepción tcp, un dispositivo de puerta de enlace o firewall debe supervisar el protocolo de enlace TCP y realizar un seguimiento del factor de escala de ventana negociado como parte de los datos de conexión TCP. Además, algunas aplicaciones y implementaciones de pila TCP en otras plataformas omiten la extensión TCP WSopt y el factor de escalado de ventanas. Por lo tanto, el host remoto que envía los datos puede enviar datos a la velocidad anunciada en el campo Ventana del encabezado TCP (256 bytes). Esto puede dar lugar a que el receptor reciba datos muy lentamente.

Al establecer el miembro BehaviorId en WsaBehaviorAutoTuning y TargetOsVersion en Windows Vista se reduce el factor de escala de ventana a 2, por lo que el campo Ventana del encabezado TCP se establece inicialmente en 16 384 bytes y el factor de escala de ventanas se establece en 2 para un tamaño de recepción de ventana verdadero inicial de 64 000 bytes. La característica de ajuste automático de ventanas puede aumentar el tamaño de recepción de la ventana true hasta 262 140 bytes estableciendo el campo Ventana en el encabezado TCP en 65 535 bytes. Una aplicación debe establecer el SIO_SET_COMPATIBILITY_MODE IOCTL en cuanto se crea un socket, ya que esta opción no tiene sentido ni se aplica después de enviar un SYN. Establecer esta opción tiene el mismo impacto que el siguiente comando: netsh interface tcp set global autotuninglevel=highlyrestricted

Tenga en cuenta que el archivo de encabezado Mswsockdef.h se incluye automáticamente en Mswsock.h o Netiodef.h, y no se debe usar directamente.

Consulte también

socket

WSAGetLastError

WSAGetOverlappedResult

WSAIoctl

WSAOVERLAPPED

WSASocketA

WSASocketW