Функция TransmitFile (mswsock.h)
Функция TransmitFile передает данные файла через подключенный дескриптор сокета. Эта функция использует диспетчер кэша операционной системы для получения файловых данных и обеспечивает высокопроизводительную передачу файловых данных через сокеты.
Синтаксис
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 .
После завершения запроса TransmitFile дескриптор сокета можно передать в вызов функции, ранее использовавшийся для установления соединения, например AcceptEx или ConnectEx. Такое повторное использование является взаимоисключающим; Например, если функция AcceptEx была вызвана для сокета, повторное использование разрешено только для последующих вызовов функции AcceptEx и запрещено для последующего вызова ConnectEx. Примечание Передача файлов на уровне сокета зависит от поведения базового транспорта. Например, сокет TCP может находиться в состоянии TCP TIME_WAIT, что приводит к задержке вызова TransmitFile .
|
|
Указывает поставщику службы Windows Sockets использовать системный поток по умолчанию для обработки длинных запросов TransmitFile . Системный поток по умолчанию можно настроить с помощью следующего параметра реестра в качестве REG_DWORD: HKEY_LOCAL_MACHINE\CurrentControlSet\Услуги\AFD\Параметры\TransmitWorker |
|
Указывает поставщику службы Windows Sockets использовать системные потоки для обработки длинных запросов TransmitFile . |
|
Предписывает драйверу использовать асинхронные вызовы процедур ядра вместо рабочих потоков для обработки длинных запросов TransmitFile . Длинные запросы TransmitFile определяются как запросы, требующие более одного считывания из файла или кэша; Таким образом, запрос зависит от размера файла и указанной длины отправляемого пакета.
Использование TF_USE_KERNEL_APC может значительно повысить производительность. Однако возможно (хотя и маловероятно), что поток, в котором инициируется контекст TransmitFile , используется для интенсивных вычислений; Эта ситуация может помешать запуску БТР. Обратите внимание, что драйвер режима ядра Winsock использует обычные APC ядра, которые запускаются каждый раз, когда поток находится в состоянии ожидания, что отличается от АПО в пользовательском режиме, которые запускаются всякий раз, когда поток находится в состоянии ожидания с оповещением, инициированном в пользовательском режиме). |
|
Немедленно завершите запрос TransmitFile без ожидания. Если этот флаг указан и TransmitFile выполняется успешно, то данные были приняты системой, но не обязательно подтверждены удаленным конце. Не используйте этот параметр с флагами TF_DISCONNECT и TF_REUSE_SOCKET.
Примечание Если отправляемый файл не находится в кэше файловой системы, запрос выполняется.
|
Возвращаемое значение
Если функция TransmitFile завершается успешно, возвращается значение TRUE. В противном случае возвращается значение FALSE. Чтобы получить расширенные сведения об ошибке, вызовите WSAGetLastError. Код ошибки WSA_IO_PENDING или ERROR_IO_PENDING указывает, что перекрывающаяся операция успешно запущена и что завершение будет указано позже. Любой другой код ошибки указывает на то, что перекрывающаяся операция не была успешно инициирована и не будет никаких указаний завершения. В этом случае приложения должны обрабатывать ERROR_IO_PENDING или WSA_IO_PENDING.
Код возврата | Описание |
---|---|
Установленное подключение прервано программой на вашем компьютере. Эта ошибка возвращается, если виртуальный канал был прерван из-за истечения времени ожидания или другого сбоя. | |
существующее соединение было принудительно завершено удаленным узлом. Эта ошибка возвращается для сокета потока, когда виртуальная цепь была сброшена удаленной стороной. Приложение должно закрыть сокет, поскольку он больше не может использоваться. | |
Система обнаружила недопустимый адрес указателя при попытке использовать аргумент указателя в вызове. Эта ошибка возвращается, если параметр lpTransmitBuffers или lpOverlapped не полностью содержится в допустимой части адресного пространства пользователя. | |
Указан недопустимый аргумент. Эта ошибка возвращается, если параметр hSocket указал сокет типа SOCK_DGRAM или SOCK_RAW. Эта ошибка возвращается, если параметру dwFlags задан флаг TF_REUSE_SOCKET , но флаг TF_DISCONNECT не задан. Эта ошибка также возвращается, если смещение, указанное в структуре OVERLAPPED , на которую указывает lpOverlapped , не находится в файле. Эта ошибка также возвращается, если для параметра nNumberOfBytesToWrite задано значение больше 2 147 483 646, максимальное значение для 32-разрядного целого числа минус 1. | |
Операция сокета обнаружила неработающих сетей. Эта ошибка возвращается, если произошел сбой сетевой подсистемы. | |
Подключение было разорвано из-за действия поддержания активности, обнаруживающего сбой во время выполнения операции. | |
Не удалось выполнить операцию с сокетом, так как в системе недостаточно места в буфере или из-за переполнения очереди. Эта ошибка также возвращается, если поставщик сокетов Windows сообщает о взаимоблокировке буфера. | |
Запрос на отправку или получение данных был запрещен, так как сокет не подключен. | |
Предпринята попытка выполнения операции с тем, что не является сокетом. Эта ошибка возвращается, если параметр hSocket не является сокетом. | |
Запрос на отправку или получение данных запрещен, так как сокет уже завершил работу в этом направлении по предыдущему запросу на завершение работы. Эта ошибка возвращается, если сокет был завершен для отправки. Невозможно вызвать TransmitFile в сокете после вызова функции завершения работы в сокете с параметром how , для которого задано значение SD_SEND или SD_BOTH. | |
Либо приложение не вызывало функцию WSAStartup , либо произошел сбой WSAStartup . Перед использованием функции TransmitFile должен быть выполнен успешный вызов WSAStartup. | |
Выполняется перекрываемая операция ввода-вывода. Это значение возвращается, если была успешно инициирована перекрывающаяся операция ввода-вывода, и указывает, что завершение будет указано позже. | |
Операция ввода-вывода прекращена из-за выхода из потока или запроса приложения. Эта ошибка возвращается, если перекрывающаяся операция была отменена из-за закрытия сокета, выполнения команды "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 будет использовать размер файла в качестве значения количества передаваемых байтов.
Рабочие станции и клиентские версии 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 |