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


Функция WSAIoctl (winsock2.h)

Функция WSAIoctl управляет режимом сокета.

Синтаксис

int WSAAPI WSAIoctl(
  [in]  SOCKET                             s,
  [in]  DWORD                              dwIoControlCode,
  [in]  LPVOID                             lpvInBuffer,
  [in]  DWORD                              cbInBuffer,
  [out] LPVOID                             lpvOutBuffer,
  [in]  DWORD                              cbOutBuffer,
  [out] LPDWORD                            lpcbBytesReturned,
  [in]  LPWSAOVERLAPPED                    lpOverlapped,
  [in]  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Параметры

[in] s

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

[in] dwIoControlCode

Код элемента управления для выполнения операции. См. ioCTLs Winsock.

[in] lpvInBuffer

Указатель на входной буфер.

[in] cbInBuffer

Размер входного буфера в байтах.

[out] lpvOutBuffer

Указатель на выходной буфер.

[in] cbOutBuffer

Размер в байтах выходного буфера.

[out] lpcbBytesReturned

Указатель на фактическое количество байтов выходных данных.

[in] lpOverlapped

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

[in] lpCompletionRoutine

Тип: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE

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

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

После успешного завершения WSAIoctl возвращает ноль. В противном случае возвращается значение SOCKET_ERROR, а определенный код ошибки можно получить путем вызова WSAGetLastError.

Код ошибки Значение
WSA_IO_PENDING
Операция, перекрываемая, была успешно инициирована, а завершение будет указано позже.
WSAENETDOWN
Сбой сетевой подсистемы.
WSAEFAULT
lpvInBuffer, lpvOutBuffer, lpcbBytesReturned, lpOverlappedили параметр lpCompletionRoutine не полностью содержится в допустимой части адресного пространства пользователя, или параметр cbInBuffer или cbOutBuffer слишком мал.
WSAEINVAL
Параметр dwIoControlCode не является допустимой командой или заданным входным параметром недопустим, или команда не применима к указанному типу сокета.
WSAEINPROGRESS
Функция вызывается при выполнении обратного вызова.
WSAENOTSOCK
Дескриптор не является сокетом.
WSAEOPNOTSUPP
Указанная команда IOCTL не может быть реализована. (Например, структуры FLOWSPEC, указанные в SIO_SET_QOS или SIO_SET_GROUP_QOS, не могут быть удовлетворены.)
WSAEWOULDBLOCK
Сокет помечается как неблокирующий, и запрошенная операция будет блокироваться.
WSAENOPROTOOPT
Параметр сокета не поддерживается в указанном протоколе. Например, попытка использовать SIO_GET_BROADCAST_ADDRESS IOCTL была сделана на сокете IPv6 или попытке использовать протокол TCP SIO_KEEPALIVE_VALS IOCTL был сделан на сокете диаграммы данных.

Замечания

Функция WSAIoctl используется для задания или извлечения операционных параметров, связанных с сокетом, протоколом транспорта или подсистемой связи.

Если оба lpOverlapped и lpCompletionRoutineNULL, сокет в этой функции будет рассматриваться как не перекрывающийся сокет. Для не перекрывающегося сокета lpOverlapped и lpCompletionRoutine параметры игнорируются, что приводит к тому, что функция будет вести себя как стандартная функция ioctlsocket, за исключением того, что функция может блокировать, если сокета находится в режиме блокировки. Если сокета находится в режиме неблокировки, эта функция может вернуть WSAEWOULDBLOCK, когда указанная операция не может быть завершена немедленно. В этом случае приложение может изменить сокет на режим блокировки и повторно отправить запрос или ждать соответствующего сетевого события (например, FD_ROUTING_INTERFACE_CHANGE или FD_ADDRESS_LIST_CHANGE в случае SIO_ROUTING_INTERFACE_CHANGE или SIO_ADDRESS_LIST_CHANGE) с помощью сообщения Windows (с помощью WSAAsyncSelect)или события (с помощью механизма уведомлений на основе WSAEventSelect).

Для перекрывающихся сокетов операции, которые не могут быть выполнены немедленно, будут инициированы, а завершение будет указано позже. Значение DWORD , указываемое параметром lpcbBytesReturned, который возвращается, может игнорироваться. Окончательное состояние завершения и возвращаемые байты можно получить, когда соответствующий метод завершения сигнализирует о завершении операции.

Любой IOCTL может блокироваться на неопределенный срок в зависимости от реализации поставщика услуг. Если приложению не удается запретить блокировку в вызове WSAIoctl, для операций ввода-вывода, которые, скорее всего, будут блокироваться:

SIO_ADDRESS_LIST_CHANGE

SIO_FINDROUTE

SIO_FLUSH

SIO_GET_QOS

SIO_GET_GROUP_QOS

SIO_ROUTING_INTERFACE_CHANGE

SIO_SET_QOS

SIO_SET_GROUP_QOS

Некоторые операции ввода-вывода, относящиеся к протоколу, также могут быть особенно вероятными для блокировки. Проверьте соответствующее приложение для конкретного протокола, чтобы получить доступную информацию.

Прототип подпрограммы завершения, на который указывает параметр lpCompletionRoutine, выглядит следующим образом:

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")


void CALLBACK CompletionRoutine (
  IN DWORD dwError,
  IN DWORD cbTransferred,
  IN LPWSAOVERLAPPED lpOverlapped,
  IN DWORD dwFlags 
);

Свойство CompletionRoutine — это заполнитель для имени функции, предоставленной приложением. Параметр dwError указывает состояние завершения перекрывающейся операции, как указано в параметре lpOverlapped. Параметр cbTransferred указывает количество полученных байтов. Параметр dwFlags не используется для этого IOCTL. Подпрограмма завершения не возвращает значение.

Можно применить схему кодирования, которая сохраняет заданное в настоящее время ioctlsocket opcodes, предоставляя удобный способ секционировать пространство идентификатора опкода столько, сколько параметр dwIoControlCode теперь является 32-разрядной сущностью. Параметр dwIoControlCode создан для обеспечения независимости протокола и поставщика при добавлении новых кодов управления при сохранении обратной совместимости с кодами элементов управления Windows Sockets 1.1 и Unix. Параметр dwIoControlCode имеет следующую форму.

Я O V T Семейство поставщиков и адресов Код
3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 
Примечание Биты в параметре dwIoControlCode dwIoControlCode, отображаемые в таблице, должны быть считываются по вертикали сверху вниз по столбцам. Таким образом, левый бит имеет бит 31, следующий бит — 30, а правый — 0.
 
Если входной буфер действителен для кода, как и IOC_IN.

O устанавливается, если выходной буфер действителен для кода, как и IOC_OUT. Коды управления с помощью входных и выходных буферов задают как I, так и O.

V устанавливается, если для кода нет параметров, как и IOC_VOID.

T — это 2-разрядное количество, определяющее тип IOCTL. Определены следующие значения:

0 IOCTL — это стандартный код IOCTL Unix, как и FIONREAD и FIONBIO.

1 IOCTL — это универсальный код IOCTL для Windows Sockets 2. Новые коды IOCTL, определенные для сокетов Windows 2, будут иметь T == 1.

2. IOCTL применяется только к определенному семейству адресов.

3 IOCTL применяется только к поставщику конкретного поставщика, как и к IOC_VENDOR. Этот тип позволяет компаниям назначать номер поставщика, который отображается в семействе поставщиков и адресов. Затем поставщик может определить новые ioCTLs, относящиеся к этому поставщику, не регистрируя IOCTL в clearinghouse, тем самым обеспечивая гибкость и конфиденциальность поставщиков.

семейство поставщиков и адресов 11-разрядное количество, определяющее поставщика, который владеет кодом (если T == 3) или содержит семейство адресов, к которому применяется код (если T == 2). Если это код IOCTL Unix (T == 0), этот параметр имеет то же значение, что и код в Unix. Если это универсальный набор сокетов Windows 2 IOCTL (T == 1), этот параметр можно использовать в качестве расширения параметра кода для предоставления дополнительных значений кода.

код 16-разрядное количество, содержащее определенный код IOCTL для операции.

Поддерживаются следующие коды IOCTL (команды) Unix.

Поддерживаются следующие команды Сокетов Windows 2.

Если перекрывающаяся операция завершается немедленно, WSAIoctl возвращает значение нуля, а параметр lpcbBytesReturned обновляется с числом байтов в выходном буфере. Если перекрывающаяся операция успешно инициируется и завершится позже, эта функция возвращает SOCKET_ERROR и указывает код ошибки WSA_IO_PENDING. В этом случае lpcbBytesReturned не обновляется. Когда перекрываемая операция завершает объем данных в выходном буфере, указывается либо через параметр cbTransferred в подпрограмме завершения (если указано), либо через параметр lpcbTransfer в WSAGetOverlappedResult.

При вызове с перекрывающимся сокетом параметр lpOverlapped должен быть допустимым в течение перекрывающейся операции. Параметр lpOverlapped содержит адрес структуры WSAOVERLAPPED.

Если параметр lpCompletionRoutineNULL, параметр hEventlpOverlapped сигнализирует, когда операция перекрывается, если она содержит допустимый дескриптор объекта события. Приложение может использовать WSAWaitForMultipleEvents или WSAGetOverlappedResult для ожидания или опроса объекта события.

примечание все операции ввода-вывода, инициированные заданным потоком, отменяются при выходе из этого потока. Для перекрывающихся сокетов ожидающие асинхронные операции могут завершиться ошибкой, если поток закрыт до завершения операций. Дополнительные сведения см. в exitThread.
 
Если lpCompletionRoutine не NULL, параметр hEvent игнорируется и может использоваться приложением для передачи сведений о контексте в подпрограмму завершения. Вызывающий объект, который передаетlpCompletionRoutine и более поздних вызовов WSAGetOverlappedResult для того же перекрывающегося запроса ввода-вывода может не задать параметр fWait для этого вызова WSAGetOverlappedResult TRUE. В этом случае использование параметра hEvent не определено, и попытка дождаться параметра hEvent приведет к непредсказуемым результатам.

Прототип подпрограммы завершения выглядит следующим образом:


void CALLBACK CompletionRoutine(
  IN DWORD dwError, 
  IN DWORD cbTransferred, 
  IN LPWSAOVERLAPPED lpOverlapped, 
  IN DWORD dwFlags 
);

Этот CompletionRoutine является заполнителем для определяемой приложением или библиотекой функции. Подпрограмма завершения вызывается только в том случае, если поток находится в состоянии оповещения. Чтобы поместить поток в оповещенное состояние, используйтефункцию WSAWaitForMultipleEvents, WaitForSingleObjectExили WaitForMultipleObjectsEx с параметром fAlertable или bAlertable значение TRUE.

Параметр dwError CompletionRoutine указывает состояние завершения перекрываемой операции, как указано lpOverlapped. Параметр cbTransferred указывает количество возвращенных байтов. В настоящее время значения флагов не определены, а dwFlags будет нулевым. Функция CompletionRoutine не возвращает значение.

Возврат из этой функции позволяет выполнять вызов другой подпрограммы завершения ожидания для этого сокета. Подпрограммы завершения можно вызывать в любом порядке, не обязательно в том же порядке, что и операции, перекрывающиеся.

совместимость

Коды IOCTL с T == 0 являются подмножеством кодов IOCTL, используемых в сокетах Berkeley. В частности, нет команды, эквивалентной FIOASYNC.
Примечание Некоторые коды IOCTL требуют дополнительных файлов заголовков. Например, для использования SIO_RCVALL IOCTL требуется файл заголовка Mstcpip.h.
 
Windows Phone 8: эта функция поддерживается для приложений Магазина Windows Phone в Windows Phone 8 и более поздних версиях.

Windows 8.1 и Windows Server 2012 R2: эта функция поддерживается для приложений Магазина Windows в Windows 8.1, Windows Server 2012 R2 и более поздних версий.

Требования

Требование Ценность
минимальные поддерживаемые клиентские Windows 8.1, Windows Vista [классические приложения | Приложения UWP]
минимальный поддерживаемый сервер Windows Server 2003 [классические приложения | Приложения UWP]
целевая платформа Виндоус
заголовка winsock2.h
библиотеки Ws2_32.lib
DLL Ws2_32.dll

См. также

Параметры сокета SOL_SOCKET

WSASocket

Функции Winsock

Справочник Winsock

getsockopt

ioctlsocket

setsockopt

сокета