Функция TransmitFile (mswsock.h)

Функция TransmitFile передает данные файла через подключенный дескриптор сокета. Эта функция использует диспетчер кэша операционной системы для получения файловых данных и обеспечивает высокопроизводительную передачу файловых данных через сокеты.

Примечание Эта функция является расширением для спецификации сокетов Windows, относящаяся к корпорации Майкрософт.

 

Синтаксис

BOOL TransmitFile(
  SOCKET                  hSocket,
  HANDLE                  hFile,
  DWORD                   nNumberOfBytesToWrite,
  DWORD                   nNumberOfBytesPerSend,
  LPOVERLAPPED            lpOverlapped,
  LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
  DWORD                   dwReserved
);

Параметры

hSocket

Дескриптор подключенного сокета. Функция TransmitFile будет передавать данные файла через этот сокет. Сокет, указанный параметром hSocket , должен быть ориентированным на подключение сокетом типа SOCK_STREAM, SOCK_SEQPACKET или SOCK_RDM.

hFile

Дескриптор открытого файла, который передает функция TransmitFile . Так как операционная система считывает данные файла последовательно, можно повысить производительность кэширования, открыв дескриптор с FILE_FLAG_SEQUENTIAL_SCAN.

Параметр hFile является необязательным. Если параметр hFile имеет значение NULL, передаются только данные в заголовке и (или) заключительном буфере. Любое дополнительное действие, например отключение или повторное использование сокета, выполняется в соответствии с параметром dwFlags .

nNumberOfBytesToWrite

Число байтов в файле для передачи. Функция TransmitFile завершается при отправке указанного количества байтов или при возникновении ошибки в зависимости от того, что произойдет раньше.

Присвойте этому параметру значение 0, чтобы передать весь файл.

nNumberOfBytesPerSend

Размер (в байтах) каждого блока данных, отправляемых в каждой операции отправки. Этот параметр используется слоем сокетов Windows для определения размера блока для операций отправки. Чтобы выбрать размер отправки по умолчанию, задайте для этого параметра нулевое значение.

Параметр nNumberOfBytesPerSend удобен для протоколов, имеющих ограничения на размер отдельных запросов на отправку.

lpOverlapped

Указатель на структуру OVERLAPPED . Если дескриптор сокета был открыт как перекрывающийся, укажите этот параметр, чтобы выполнить перекрывающиеся (асинхронные) операции ввода-вывода. По умолчанию дескрипторы сокетов открываются как перекрывающиеся.

С помощью параметра lpOverlapped можно указать 64-разрядное смещение в файле, с которого начинается передача данных файла, задав элемент Offset и OffsetHigh структуры OVERLAPPED . Если lpOverlapped является указателем NULL , передача данных всегда начинается с текущего смещения байтов в файле.

Если значение lpOverlapped не равно NULL, перекрытие ввода-вывода может не завершиться до возврата TransmitFile . В этом случае функция TransmitFile возвращает значение FALSE, а WSAGetLastError — ERROR_IO_PENDING или WSA_IO_PENDING. Это позволяет вызывающей объекту продолжать обработку до завершения операции передачи файла. Windows установит событие, заданное элементом hEvent структуры OVERLAPPED или сокетом, указанным в hSocket, в состояние сигнала после завершения запроса передачи данных.

lpTransmitBuffers

Указатель на TRANSMIT_FILE_BUFFERS структуру данных, содержащую указатели на данные, отправляемые до и после отправки данных файла. Для этого параметра следует задать указатель NULL , если вы хотите передавать только данные файла.

dwReserved

Набор флагов, используемых для изменения поведения вызова функции TransmitFile . Параметр dwFlags может содержать сочетание следующих параметров, определенных в файле заголовка Mswsock.h :

Flag Значение
TF_DISCONNECT
Запустить отключение уровня транспорта, после того как все данные файла поставлены в очередь на передачу.
TF_REUSE_SOCKET
Подготовьте дескриптор сокета для повторного использовать. Этот флаг действителен, только если также указан TF_DISCONNECT .

После завершения запроса TransmitFile дескриптор сокета можно передать в вызов функции, ранее использовавшийся для установления соединения, например AcceptEx или ConnectEx. Такое повторное использование является взаимоисключающим; Например, если функция AcceptEx была вызвана для сокета, повторное использование разрешено только для последующих вызовов функции AcceptEx и запрещено для последующего вызова ConnectEx.

Примечание Передача файлов на уровне сокета зависит от поведения базового транспорта. Например, сокет TCP может находиться в состоянии TCP TIME_WAIT, что приводит к задержке вызова TransmitFile .
 
TF_USE_DEFAULT_WORKER
Указывает поставщику службы Windows Sockets использовать системный поток по умолчанию для обработки длинных запросов TransmitFile . Системный поток по умолчанию можно настроить с помощью следующего параметра реестра в качестве REG_DWORD:

HKEY_LOCAL_MACHINE\CurrentControlSet\Услуги\AFD\Параметры\TransmitWorker

TF_USE_SYSTEM_THREAD
Указывает поставщику службы Windows Sockets использовать системные потоки для обработки длинных запросов TransmitFile .
TF_USE_KERNEL_APC
Предписывает драйверу использовать асинхронные вызовы процедур ядра вместо рабочих потоков для обработки длинных запросов TransmitFile . Длинные запросы TransmitFile определяются как запросы, требующие более одного считывания из файла или кэша; Таким образом, запрос зависит от размера файла и указанной длины отправляемого пакета.

Использование TF_USE_KERNEL_APC может значительно повысить производительность. Однако возможно (хотя и маловероятно), что поток, в котором инициируется контекст TransmitFile , используется для интенсивных вычислений; Эта ситуация может помешать запуску БТР. Обратите внимание, что драйвер режима ядра Winsock использует обычные APC ядра, которые запускаются каждый раз, когда поток находится в состоянии ожидания, что отличается от АПО в пользовательском режиме, которые запускаются всякий раз, когда поток находится в состоянии ожидания с оповещением, инициированном в пользовательском режиме).

TF_WRITE_BEHIND
Немедленно завершите запрос TransmitFile без ожидания. Если этот флаг указан и TransmitFile выполняется успешно, то данные были приняты системой, но не обязательно подтверждены удаленным конце. Не используйте этот параметр с флагами TF_DISCONNECT и TF_REUSE_SOCKET.
Примечание Если отправляемый файл не находится в кэше файловой системы, запрос выполняется.
 

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

Если функция TransmitFile завершается успешно, возвращается значение TRUE. В противном случае возвращается значение FALSE. Чтобы получить расширенные сведения об ошибке, вызовите WSAGetLastError. Код ошибки WSA_IO_PENDING или ERROR_IO_PENDING указывает, что перекрывающаяся операция успешно запущена и что завершение будет указано позже. Любой другой код ошибки указывает на то, что перекрывающаяся операция не была успешно инициирована и не будет никаких указаний завершения. В этом случае приложения должны обрабатывать ERROR_IO_PENDING или WSA_IO_PENDING.

Код возврата Описание
WSAECONNABORTED
Установленное подключение прервано программой на вашем компьютере. Эта ошибка возвращается, если виртуальный канал был прерван из-за истечения времени ожидания или другого сбоя.
WSAECONNRESET
существующее соединение было принудительно завершено удаленным узлом. Эта ошибка возвращается для сокета потока, когда виртуальная цепь была сброшена удаленной стороной. Приложение должно закрыть сокет, поскольку он больше не может использоваться.
WSAEFAULT
Система обнаружила недопустимый адрес указателя при попытке использовать аргумент указателя в вызове. Эта ошибка возвращается, если параметр lpTransmitBuffers или lpOverlapped не полностью содержится в допустимой части адресного пространства пользователя.
WSAEINVAL
Указан недопустимый аргумент. Эта ошибка возвращается, если параметр hSocket указал сокет типа SOCK_DGRAM или SOCK_RAW. Эта ошибка возвращается, если параметру dwFlags задан флаг TF_REUSE_SOCKET , но флаг TF_DISCONNECT не задан. Эта ошибка также возвращается, если смещение, указанное в структуре OVERLAPPED , на которую указывает lpOverlapped , не находится в файле. Эта ошибка также возвращается, если для параметра nNumberOfBytesToWrite задано значение больше 2 147 483 646, максимальное значение для 32-разрядного целого числа минус 1.
WSAENETDOWN
Операция сокета обнаружила неработающих сетей. Эта ошибка возвращается, если произошел сбой сетевой подсистемы.
WSAENETRESET
Подключение было разорвано из-за действия поддержания активности, обнаруживающего сбой во время выполнения операции.
WSAENOBUFS
Не удалось выполнить операцию с сокетом, так как в системе недостаточно места в буфере или из-за переполнения очереди. Эта ошибка также возвращается, если поставщик сокетов Windows сообщает о взаимоблокировке буфера.
WSAENOTCONN
Запрос на отправку или получение данных был запрещен, так как сокет не подключен.
WSAENOTSOCK
Предпринята попытка выполнения операции с тем, что не является сокетом. Эта ошибка возвращается, если параметр hSocket не является сокетом.
WSAESHUTDOWN
Запрос на отправку или получение данных запрещен, так как сокет уже завершил работу в этом направлении по предыдущему запросу на завершение работы. Эта ошибка возвращается, если сокет был завершен для отправки. Невозможно вызвать TransmitFile в сокете после вызова функции завершения работы в сокете с параметром how , для которого задано значение SD_SEND или SD_BOTH.
WSANOTINITIALISED
Либо приложение не вызывало функцию WSAStartup , либо произошел сбой WSAStartup . Перед использованием функции TransmitFile должен быть выполнен успешный вызов WSAStartup.
WSA_IO_PENDING
Выполняется перекрываемая операция ввода-вывода. Это значение возвращается, если была успешно инициирована перекрывающаяся операция ввода-вывода, и указывает, что завершение будет указано позже.
WSA_OPERATION_ABORTED
Операция ввода-вывода прекращена из-за выхода из потока или запроса приложения. Эта ошибка возвращается, если перекрывающаяся операция была отменена из-за закрытия сокета, выполнения команды "SIO_FLUSH" в WSAIoctl или потока, который инициировал перекрывающийся запрос, завершился до завершения операции.
Примечание Все операции ввода-вывода, инициированные данным потоком, отменяются при выходе из этого потока. Для перекрывающихся сокетов ожидающие асинхронные операции могут завершиться ошибкой, если поток будет закрыт до завершения асинхронных операций. Дополнительные сведения см. в разделе ExitThread.
 

Комментарии

Функция TransmitFile использует диспетчер кэша операционной системы для получения файловых данных и обеспечивает высокопроизводительную передачу файловых данных через сокеты.

Функция TransmitFile поддерживает только сокеты, ориентированные на подключение, типа SOCK_STREAM, SOCK_SEQPACKET и SOCK_RDM. Сокеты типа SOCK_DGRAM и SOCK_RAW не поддерживаются. Функцию TransmitPackets можно использовать с сокетами типа SOCK_DGRAM.

Максимальное число байтов, которые могут быть переданы с помощью одного вызова функции TransmitFile , составляет 2 147 483 646. Максимальное значение для 32-разрядного целого числа минус 1. Максимальное количество байтов для отправки в одном вызове включает все данные, отправленные до или после данных файла, на которые указывает параметр lpTransmitBuffers , а также значение, указанное в параметре nNumberOfBytesToWrite для длины отправляемых данных файла. Если приложению необходимо передать файл размером более 2 147 483 646 байт, то с каждым вызовом можно использовать несколько вызовов функции TransmitFile , передавая не более 2 147 483 646 байт. Установка для параметра nNumberOfBytesToWrite значения 0 для файла размером более 2 147 483 646 байт также завершится ошибкой, так как в этом случае функция TransmitFile будет использовать размер файла в качестве значения количества передаваемых байтов.

Примечание Указатель функции для функции TransmitFile должен быть получен во время выполнения путем вызова функции WSAIoctl с указанным SIO_GET_EXTENSION_FUNCTION_POINTER кодом операции. Входной буфер, передаваемый в функцию WSAIoctl , должен содержать WSAID_TRANSMITFILE, глобальный уникальный идентификатор (GUID), значение которого определяет функцию расширения TransmitFile . При успешном выполнении выходные данные, возвращаемые функцией WSAIoctl , содержат указатель на функцию TransmitFile . GUID WSAID_TRANSMITFILE определяется в файле заголовка Mswsock.h .
 
Примечание. TransmitFile не работает на транспортах, выполняющих собственную буферизацию. Транспорты с установленным флагом TDI_SERVICE_INTERNAL_BUFFERING, например ADSP, выполняют собственную буферизацию. Так как Уровень передачи данных достигает повышения производительности, отправляя данные непосредственно из файлового кэша. Транспорты, для которых истекает буферное пространство для определенного соединения, не обрабатываются TransmitFile, и в результате переполнения буферного пространства в соединении , TransmitFile возвращает STATUS_DEVICE_NOT_READY.
 
Функция TransmitFile была в основном добавлена в Winsock для использования высокопроизводительных серверных приложений (например, веб-серверами и ftp-серверами).

Рабочие станции и клиентские версии Windows оптимизируют функцию TransmitFile для минимального использования памяти и ресурсов, ограничивая количество одновременных операций TransmitFile , разрешенных в системе, максимум двумя. В Windows Vista, Windows XP, Windows 2000 Профессиональная и Windows NT Workstation 3.51 и более поздних версий одновременно обрабатываются только два незавершенных запроса TransmitFile. Третий запрос будет ожидать завершения одного из предыдущих запросов.

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

HKEY_LOCAL_MACHINE\CurrentControlSet\Услуги\AFD\Параметры\MaxActiveTransmitFileCount

Если функция TransmitFile вызывается с сокетом TCP (протокол IPPROTO_TCP) с указанными флагами TF_DISCONNECT и TF_REUSE_SOCKET , вызов не будет завершен до тех пор, пока не будут выполнены два следующих условия.

  • Все ожидающие получения данные, отправленные удаленной стороной (полученные до FIN с удаленной стороны) в сокете TCP были считаны.
  • Удаленная сторона закрыла подключение (завершено корректное закрытие TCP-подключения).

Если функция TransmitFile вызывается с параметром lpOverlapped , имеющим значение NULL, операция выполняется как синхронный ввод-вывод. Функция не будет завершена до отправки файла.

Windows Phone 8. Эта функция поддерживается для приложений Магазина Windows Phone на Windows Phone 8 и более поздних версиях.

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

Примечания для QoS

Функция TransmitFile позволяет установить два флага, TF_DISCONNECT или TF_REUSE_SOCKET, которые возвращают сокет в состояние "отключен, повторно используется" после передачи файла. Эти флаги не следует использовать в сокете, где было запрошено качество обслуживания, так как поставщик услуг может немедленно удалить любое качество обслуживания, связанное с сокетом, до завершения передачи файла. Лучший подход для сокета с поддержкой QoS — просто вызвать функцию closesocket после завершения передачи файлов, а не полагаться на эти флаги.

Требования

Требование Значение
Минимальная версия клиента Windows 8.1, Windows Vista [классические приложения | Приложения UWP]
Минимальная версия сервера Windows Server 2003 [классические приложения | Приложения UWP]
Целевая платформа Windows
Header mswsock.h (включая Mswsock.h)
Библиотека Mswsock.lib
DLL Mswsock.dll

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

ExitThread

ПЕРЕКРЫВАЮЩИХСЯ

TRANSMIT_FILE_BUFFERS

TransmitPackets

WSASend

closesocket