С sendfile (), можно ли узнать, когда in_fd находится в EOF? - PullRequest
4 голосов
/ 13 сентября 2010

Читая справочную страницу системного вызова Linux sendfile, я задаюсь вопросом, возможно ли, чтобы вызывающая программа узнала, когда in_fd в EOF.Предположительно, это может быть сигнализировано возвращаемым значением 0, но это приводит к вопросу о том, что фактически означает возвращаемое значение 0.Если sendfile похоже на write, то возвращаемое значение 0 будет означать, что было скопировано 0 байт.Но если sendfile похоже на read, то возвращаемое значение 0 будет означать EOF.Нужно ли заранее знать, сколько байтов нужно скопировать с in_fd на out_fd, чтобы использовать sendfile?Что это значит, когда sendfile возвращает 0?

Ответы [ 4 ]

4 голосов
/ 13 сентября 2010

Я не думаю, что есть какой-то прямой способ узнать это, но это не должно иметь большого значения.Обычно вы находите размер входного файла через stat/fstat и используете его для подсчета вашего перевода.Конец сокета не будет иметь для вас значения.

Единственная ситуация, в которой это должно быть проблематично, - это если вы хотите передать файл, который увеличивается или уменьшается.Учитывая, что входной файл должен быть mmap-ed, и плохие вещи, которые могут случиться (без какого-либо умного кода) с mmap в этих ситуациях, вы, вероятно, просто не должны использовать sendfile для этих случаев.

3 голосов
/ 07 мая 2011

Вы можете использовать параметр смещения для счетчика чтения.

По данным справочной страницы

Если смещение не равно NULL, то оно указывает на переменную, содержащую смещение файла, с которого sendfile () начнет чтение данных из in_fd. Когда sendfile () вернется, эта переменная будет установлена ​​на смещение байта, следующего за последним прочитанным байтом. Если смещение не равно NULL, то sendfile () не изменяет текущее смещение файла in_fd; в противном случае текущее смещение файла корректируется с учетом количества байтов, считанных из in_fd.

count - это количество байтов, которое нужно скопировать между дескрипторами файла.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ Если передача прошла успешно, возвращается число байтов, записанных в out_fd. В случае ошибки возвращается -1 и значение errno устанавливается соответствующим образом.

и yes означает, что возвращаемое значение 0 означает отсутствие данных, скопированных в сокет записи.

0 голосов
/ 09 декабря 2013

в моем случае, если файл rsync обрезан, приложение использует sendfile для передачи файла одновременно. Я нахожу приложение есть процессор 100% в состоянии, я исправляю мой код обратитесь к следующей статье, вопрос исчезнет. http://www.linuxjournal.com/article/6345

смысл в том, чтобы использовать F_SETLEASE для получения файлов аренды для вашего приложения.

0 голосов
/ 28 августа 2012

Можно предположить, что EOF достигнут, когда число отправленных байтов равно 0:

sent = sendfile(out_fd, in_fd, &offset, nbytes);
if (sent == 0) {
    // EOF
    ...
}

Это предположение работает и в случае неблокирующих сокетов.

...