Поделиться через


Код элемента управления SIO_SET_COMPATIBILITY_MODE

Описание

Код управления SIO_SET_COMPATIBILITY_MODE запрашивает, как сетевой стек должен обрабатывать определенные поведения, для которых способ обработки поведения по умолчанию может отличаться в разных версиях Windows.

Для выполнения этой операции вызовите функцию WSAIoctl или WSPIoctl со следующими параметрами.

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.
);

Параметры

s

Дескриптор, определяющий сокет.

dwIoControlCode

Код элемента управления для операции. Используйте SIO_SET_COMPATIBILITY_MODE для этой операции.

lpvInBuffer

Указатель на входной буфер. Этот параметр должен указывать на структуру WSA_COMPATIBILITY_MODE .

cbInBuffer

Размер входного буфера в байтах. Этот параметр должен быть равен или больше размера структуры WSA_COMPATIBILITY_MODE , на которую указывает параметр lpvInBuffer .

lpvOutBuffer

Указатель на выходной буфер. Этот параметр не используется для данной операции.

cbOutBuffer

Размер выходного буфера в байтах. Для этого параметра необходимо задать нулевое значение.

lpcbBytesReturned

Указатель на переменную, которая получает размер в байтах данных, хранящихся в выходном буфере. Этот возвращаемый параметр указывает на значение DWORD , равное нулю для данной операции, так как выходные данные отсутствуют.

lpvOverlapped

Указатель на структуру WSAOVERLAPPED .

Если сокеты были созданы без перекрываемого атрибута, параметр lpOverlapped игнорируется.

Если объект был открыт с перекрывающимся атрибутом, а параметр lpOverlapped не равен NULL, операция выполняется как перекрываемая (асинхронная) операция. В этом случае параметр lpOverlapped должен указывать на допустимую структуру WSAOVERLAPPED .

Для перекрывающихся операций функция WSAIoctl или WSPIoctl возвращается немедленно, а соответствующий метод завершения получает сигнал о завершении операции. В противном случае функция не возвращается, пока операция не будет завершена или не возникнет ошибка.

lpCompletionRoutine

Тип: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

Указатель на подпрограмму завершения, вызываемую при завершении операции (игнорируется для неперекрывающихся сокетов).

lpThreadId

Указатель на структуру WSATHREADID , которая будет использоваться поставщиком в последующем вызове WPUQueueApc. Поставщик должен хранить указанную структуру WSATHREADID (не указатель на нее), пока не будет возвращена функция WPUQueueApc .

Примечание Этот параметр применяется только к функции WSPIoctl .

lpErrno

Указатель на код ошибки.

Примечание Этот параметр применяется только к функции WSPIoctl .

Возвращаемое значение

Если операция завершается успешно, функция WSAIoctl или WSPIoctl возвращает ноль.

Если операция завершается сбоем или находится в состоянии ожидания, функция WSAIoctl или WSPIoctl возвращает SOCKET_ERROR. Чтобы получить расширенные сведения об ошибке, вызовите WSAGetLastError.

Код ошибки Значение
WSA_IO_PENDING Перекрываемая операция была успешно инициирована, и ее завершение будет указано позже.
WSA_OPERATION_ABORTED Перекрываемая операция была отменена из-за закрытия сокета или выполнения команды IOCTL SIO_FLUSH .
WSAEFAULT Параметр lpOverlapped или lpCompletionRoutine не полностью содержится в допустимой части адресного пространства пользователя.
WSAEINPROGRESS Функция вызывается при выполнении обратного вызова.
WSAEINTR Блокирующая операция была прервана.
WSAEINVAL Параметр dwIoControlCode не является допустимой командой, или указанный входной параметр недопустим, либо команда не применима к указанному типу сокета. Эта ошибка возвращается, если параметр cbInBuffer меньше размера структуры WSA_COMPATIBILITY_MODE .
WSAENETDOWN Произошел сбой сетевой подсистемы.
WSAENOPROTOOPT Параметр сокета не поддерживается в указанном протоколе.
WSAENOTCONN Сокет не подключен.
WSAENOTSOCK Дескриптор не является сокетом.
WSAEOPNOTSUPP Указанная команда IOCTL не поддерживается. Эта ошибка возвращается, если поставщик транспорта не поддерживает SIO_SET_COMPATIBILITY_MODE IOCTL. Эта ошибка также возвращается при попытке использовать SIO_SET_COMPATIBILITY_MODE IOCTL в сокете датаграммы.

Комментарии

SIO_SET_COMPATIBILITY_MODE IOCTL запрашивает, как сетевой стек должен обрабатывать определенные поведения, для которых способ обработки по умолчанию может отличаться в разных версиях Windows. Структура входных аргументов для SIO_SET_COMPATIBILITY_MODE указывается в структуре WSA_COMPATIBILITY_MODE , определенной в файле заголовка Mswsockdef.h . Указатель на структуру WSA_COMPATIBILITY_MODE передается в параметре cbInBuffer . Эта структура определяется следующим образом:

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

Значение, указанное в элементе BehaviorId , указывает на запрошенное поведение. Значение, указанное в элементе TargetOsVersion , указывает версию Windows, запрашиваемую для поведения.

Элемент BehaviorId может быть одним из значений из типа перечисления WSA_COMPATIBILITY_BEHAVIOR_ID , определенного в файле заголовка Mswsockdef.h . Ниже приведены возможные значения для элемента BehaviorId .

Термин Описание
WsaBehaviorAll Это эквивалентно запросу всех возможных совместимых поведений, определенных для WSA_COMPATIBILITY_BEHAVIOR_ID.
WsaBehaviorReceiveBuffering Если для элемента TargetOsVersion задано значение для Windows Vista или более поздней версии, уменьшение размера буфера приема TCP в этом сокете с помощью параметра сокета SO_RCVBUF разрешено даже после установки TCP-подключения. Если для элемента TargetOsVersion задано значение, предшествующее Windows Vista, уменьшение размера буфера приема TCP в этом сокете с помощью параметра сокета SO_RCVBUF не допускается после установки подключения.
WsaBehaviorAutoTuning Если для элемента TargetOsVersion задано значение для Windows Vista или более поздней версии, включена автоматическая настройка окна получения, а коэффициент масштабирования окна TCP уменьшается до 2 со значения по умолчанию 8. Если для Параметра TargetOsVersion задано значение, предшествующее Windows Vista, автоматическая настройка окна получения отключена. Параметр масштабирования окна TCP также отключен, а максимальный размер окна получения true ограничен 65 535 байтами. Параметр масштабирования окна TCP не может быть согласован при подключении, даже если для этого сокета был вызван параметр SO_RCVBUF , указывающий значение, превышающее 65 535 байт, до установки подключения.

Элемент TargetOsVersion может быть одной из констант версии NTDDI, определенных в файле заголовка Sdkddkver.h . Ниже приведены некоторые возможные значения для элемента TargetOsVersion .

Термин Описание
NTDDI_LONGHORN Целевое поведение используется по умолчанию для Windows Vista.
NTDDI_WS03 Целевое поведение является поведением по умолчанию для Windows Server 2003.
NTDDI_WINXP Целевое поведение используется по умолчанию для Windows XP.
NTDDI_WIN2K Целевое поведение используется по умолчанию для Windows 2000.

Основное влияние элемента TargetOsVersion заключается в том, задано ли для этого элемента значение, равное или большее NTDDI_LONGHORN.

Производительность TCP зависит не только от скорости передачи, но и от продукта скорости передачи и времени задержки приема-передачи. Этот продукт с задержкой пропускной способности измеряет объем данных, которые будут "заполнять канал". Этот продукт с задержкой пропускной способности представляет собой буферное пространство, необходимое отправителю и получателю для получения максимальной пропускной способности tcp-подключения по пути. Это буферное пространство представляет объем неподтвержденных данных, которые должен обрабатывать TCP, чтобы обеспечить заполнение конвейера. Проблемы с производительностью TCP возникают, когда продукт с задержкой пропускной способности большой. Сетевой путь, работающий в таких условиях, часто называется "длинным, жирным каналом". Примеры включают в себя высокопроизводительные пакеты спутниковых каналов, высокоскоростные беспроводные каналы и наземные волоконно-оптические связи на большие расстояния.

Заголовок TCP использует 16-битовое поле данных (поле Window в заголовке TCP-пакета) для передачи размера окна получения отправителю. Таким образом, наибольшее окно, которое можно использовать, составляет 65 535 байт. Чтобы обойти это ограничение, был добавлен параметр расширения TCP, TCP Window Scale, для высокопроизводительного tcp-протокола TCP, чтобы разрешить окна размером более 65 535 байт. Параметр масштабирования окна TCP (WSopt) определен в RFC 1323, доступном на веб-сайте IETF. Расширение WSopt расширяет определение окна TCP до 32 бит, используя однобайтовый логарифмический коэффициент масштабирования, чтобы расширить 16-разрядное поле Window в заголовке TCP. Расширение WSopt определяет неявный коэффициент масштабирования (от 2 до некоторой мощности), который используется для умножения значения размера окна, найденного в заголовке TCP, для получения истинного размера окна. Таким образом, коэффициент масштабирования окна 8 приведет к тому, что истинный размер окна будет равен значению поля Window в заголовке TCP, умноженному на 2^8 или 256. Таким образом, если для поля Window в заголовке TCP задано максимальное значение 65 535 байт, а коэффициент масштабирования WSopt был согласован со значением 8, истинный размер окна будет составлять 16 776 960 байт.

Истинный размер окна получения и, следовательно, коэффициент масштабирования определяется максимальным пространством буфера приема. Это максимальный объем буфера — это объем данных, который получатель TCP позволяет отправителю TCP отправлять, прежде чем ждать подтверждения. После установки подключения размер окна получения объявляется в каждом сегменте TCP (поле Window в заголовке TCP). Объявление максимального объема данных, которые может отправить отправитель, является механизмом управления потоком на стороне получателя, который предотвращает отправку отправителем данных, которые получатель не может хранить. Отправляющий узел может отправлять только максимальный объем данных, объявленных получателем, прежде чем ожидать подтверждения и обновления размера окна получения.

В Windows Server 2003 и Windows XP максимальное пространство буфера приема, представляющее размер окна приема для стека TCP/IP, имеет значение по умолчанию в зависимости от скорости канала интерфейса отправки. Фактическое значение автоматически адаптируется к четным приращениям максимального размера сегмента (MSS), согласованного во время установления TCP-подключения. Таким образом, для канала со значением 10 Мбит/с размер окна приема по умолчанию обычно устанавливается значение 16 000 байт, а для канала со значением 100 Мбит/с размер окна приема по умолчанию — 65 535 байт.

В Windows Server 2003 и Windows XP истинный максимальный размер окна получения для стека TCP/IP можно настроить вручную, используя следующие значения реестра в определенном интерфейсе или для всей системы:

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

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

Значение реестра для TCPWindowSize может быть не более 65 535 байт, если расширение WSopt не используется, или не более 1 073 741 823 байт при использовании расширения WSopt (поддерживается максимальный коэффициент масштабирования 4). Без масштабирования окна приложение может достичь пропускной способности примерно 5 мегабит в секунду (Мбит/с) на пути со временем кругового пути 100 миллисекунд (RTT), независимо от пропускной способности пути. Эту пропускную способность можно масштабировать до гигабит в секунду (Гбит/с) с помощью масштабирования окна, что позволяет TCP согласовывать коэффициент масштабирования для размера окна во время установки подключения.

В Windows Server 2003 и Windows XP расширение WSopt можно включить, задав следующее значение реестра.

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

Значение реестра Tcp1323Opts имеет кодировку DWORD , чтобы при задании бита 0 было включено расширение TCP WSopt. Если задан бит 1, включен параметр метки времени TCP (TSopt), определенный в RFC 1323. Поэтому расширение WSopt будет включать значение 1 или 3.

В Windows Server 2003 и Windows XP по умолчанию значения реестра TCPWindowSize и Tcp1323Opts не создаются. Поэтому по умолчанию расширение WSopt отключено, а размер окна приема TCP устанавливается системой на максимальное значение до 65 535 байт в зависимости от скорости канала. Если масштабирование окон включено в Windows Server 2003 и Windows XP путем установки значения реестра Tcp1323Opts, масштабирование окон в TCP-подключении по-прежнему используется только в том случае, если отправитель и получатель включают параметр масштабирования окна TCP в сегмент синхронизации (SYN), отправляемый друг другу для согласования коэффициента масштабирования окна. Если при подключении используется масштабирование окна, для поля Window в заголовке TCP задано значение 65 535 байт, а коэффициент масштабирования окна используется для настройки истинного размера окна приема вверх по коэффициенту масштабирования окна, согласованному при установке подключения.

Приложение может указать размер окна получения TCP для подключения с помощью параметра сокета SO_RCVBUF . Размер окна приема TCP для сокета можно увеличить в любое время с помощью SO_RCVBUF, но его можно уменьшить только до установки подключения. Чтобы использовать масштабирование окон, приложение должно указать размер окна более 65 535 байт при использовании параметра сокета SO_RCVBUF перед подключением.

Идеальное значение для размера окна приема TCP часто бывает трудно определить. Чтобы заполнить емкость сети между отправителем и получателем, в качестве размера окна получения следует задать продукт задержки пропускной способности для подключения, который является пропускной способностью, умноженной на время кругового пути. Даже если приложение может правильно определить продукт с задержкой пропускной способности, по-прежнему неизвестно, как быстро принимающее приложение будет получать данные из буфера входящих данных (скорость извлечения приложения). Несмотря на поддержку масштабирования окон TCP, максимальный размер окна получения в Windows Server 2003 и Windows XP по-прежнему может ограничивать пропускную способность, так как это фиксированный максимальный размер для всех TCP-подключений (если не указано для каждого приложения с помощью SO_RCVBUF), что может повысить пропускную способность для некоторых подключений и уменьшить пропускную способность для других. Кроме того, фиксированный максимальный размер окна получения для TCP-подключения не зависит от изменяющихся условий сети.

Чтобы решить проблему правильного определения значения максимального размера окна получения для TCP-подключения на основе текущих условий сети, стек TCP/IP в Windows Vista поддерживает функцию автоматической настройки окна получения. Если эта функция включена, автоматическая настройка окна получения постоянно определяет оптимальный истинный размер окна приема, измеряя продукт с задержкой пропускной способности и скорость извлечения приложения, а также корректирует истинный максимальный размер окна приема в зависимости от изменяющихся условий сети. Автоматическая настройка окна получения включает расширение TCP WSopt по умолчанию, позволяя использовать до 16 776 960 байт для истинного размера окна. По мере передачи данных через соединение стек TCP/IP отслеживает подключение, измеряет текущий продукт с задержкой пропускной способности для подключения и скорости приема приложения, а также корректирует фактический размер окна получения для оптимизации пропускной способности. Стек TCP/IP изменяет значение поля Window в заголовке TCP в зависимости от условий сети, так как коэффициент масштабирования WSopt фиксируется при первой установке подключения.

Стек TCP/IP в Windows Vista больше не использует значения реестра TCPWindowSize . При повышении пропускной способности между одноранговыми узлами TCP увеличивается использование пропускной способности сети во время передачи данных. Если все приложения оптимизированы для получения данных TCP, то общее использование сети может значительно увеличиться, что делает использование качества обслуживания (QoS) более важным в сетях, работающих с или близкой к ней емкости.

Поведение по умолчанию в Windows Vista для буферизации приема, если SIO_SET_COMPATIBILITY_MODE не задано с помощью WsaBehaviorReceiveBuffering , заключается в том, что после установки подключения не допускается уменьшение размера окна получения с помощью параметра сокета SO_RCVBUF .

Поведение по умолчанию в Windows Vista для автоматической настройки , если SIO_SET_COMPATIBILITY_MODE не задано с помощью WsaBehaviorAutoTuning , заключается в том, что стек будет получать автоматическую настройку окна с коэффициентом масштабирования окна 8. Обратите внимание, что если приложение задает допустимый размер окна получения с параметром сокета SO_RCVBUF , стек будет использовать указанный размер, а автоматическая настройка получения окна будет отключена. Автонастройка Windows также может быть полностью отключена с помощью следующей команды , netsh interface tcp set global autotuninglevel=disabledв этом случае указание WsaBehaviorAutoTuning не повлияет. Автоматическую настройку получения окна также можно отключить на основе групповой политики, установленной в Windows Server 2008.

Параметр WsaBehaviorAutoTuning необходим в Windows Vista для некоторых устройств шлюза Интернета и брандмауэров, которые неправильно поддерживают потоки данных для TCP-подключений, использующих расширение WSopt и коэффициент масштабирования Windows. В Windows Vista получатель по умолчанию согласовывает коэффициент масштабирования окна 8 для максимального истинного размера окна в 16 776 960 байт. Когда данные начинают передаваться по быстрому каналу, Windows изначально начинается с истинного размера окна 64 килобайта, установив для поля Window заголовка TCP значение 256 и установив коэффициент масштабирования окна равным 8 в параметрах TCP (256*2^8=64 КБ). Некоторые устройства и брандмауэры интернет-шлюзов игнорируют коэффициент масштабирования окна и смотрят только на объявленное поле Window в заголовке TCP, указанном как 256, и удаляют входящие пакеты для подключения, которые содержат более 256 байт данных TCP. Для поддержки масштабирования окон приема TCP устройство шлюза или брандмауэр должны отслеживать подтверждение TCP и отслеживать согласованный коэффициент масштабирования окна в рамках данных TCP-подключения. Кроме того, некоторые приложения и реализации стека TCP на других платформах игнорируют расширение TCP WSopt и коэффициент масштабирования окна. Таким образом, удаленный узел, отправляя данные, может отправлять данные со скоростью, объявленной в поле Window заголовка TCP (256 байт). Это может привести к очень медленному получению данных получателем.

Если задать для элемента BehaviorId значение WsaBehaviorAutoTuning , а для TargetOsVersion — Windows Vista, коэффициент масштабирования окна уменьшается до 2, поэтому для поля Window в заголовке TCP изначально задано значение 16 384 байта, а для коэффициента масштабирования окна устанавливается значение 2 для начального размера получения истинного окна 64 КБ. После этого функция автоматической настройки окна может увеличить истинный размер получения окна до 262 140 байт, установив для поля Window в заголовке TCP значение 65 535 байт. Приложение должно задать SIO_SET_COMPATIBILITY_MODE IOCTL сразу после создания сокета, так как этот параметр не имеет смысла и не применяется после отправки SYN. Установка этого параметра оказывает такое же влияние, как и следующая команда: netsh interface tcp set global autotuninglevel=highlyrestricted

Обратите внимание, что файл заголовка Mswsockdef.h автоматически включается в Mswsock.h или Netiodef.h и не должен использоваться напрямую.

См. также раздел

Сокета

WSAGetLastError

WSAGetOverlappedResult

WSAIoctl

WSAOVERLAPPED

WSASocketA

WSASocketW