TransmitFile работает на каналах? - PullRequest
2 голосов
/ 13 января 2011

Документы для функции winsock TransmitFile говорят "файл", а не "дескриптор файла", так что, возможно, ответ - нет?Если я не могу использовать TransmitFile для отправки данных из канала через сокет, могу ли я использовать какой-либо другой метод нулевого копирования?

1 Ответ

3 голосов
/ 13 января 2011

Чтобы выполнить ручную передачу с нулевым копированием, вам нужно открыть сокет и файл в режиме наложения и связать их с портом завершения ввода-вывода. Затем вы выполняете чтение файла, а когда чтение файла завершается, вы передаете заполненный буфер для записи в сокет. Затем вы, вероятно, можете настроить это, отрегулировав размер буфера отправки на сокете, чтобы предотвратить копирование, и выбрав правильные флаги при открытии файла.

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

Обратите внимание, что это не так эффективно, как использование самого TransmitFile(), поскольку это позволяет избежать переходов ядра к пользователю, которые происходят, чтобы уведомить вас о завершении чтения и выполнить вызов записи.

В ответ на первую часть вашего вопроса, что произойдет, если вы попытаетесь?

...